【问题标题】:Multiple Event Listeners inside of Object Method Javascript HTML DOM对象方法Javascript HTML DOM中的多个事件监听器
【发布时间】:2015-10-22 01:02:37
【问题描述】:

这里有一些答案以及我通过谷歌找到的一些东西,几乎可以让我到达我想去的地方,但有些东西告诉我我正在解决这个问题并希望得到一些帮助。

我正在尝试简化将多个事件侦听器添加到同一元素的过程。我认为我的问题只是在调用 controller.listenz() 函数时我没有使用正确的范围。任何帮助将不胜感激。

我目前遇到的错误是在 listenz() 方法中抛出的,并告诉我“fn 不是函数”。我猜这是有道理的,它是一个对象,但我该如何解决呢?

JSFIDDLE

Javascript

 var controller = {

     realtime: true,
     listenz: function(ele, e, fn, c, o) {

         //validate
         if (!(e instanceof Array)) {
             throw 'Javascript Listener:  Error 642';
         }


         var h = function() {
            fn.apply(this, o && o instanceof Array ? o : []);
         };


         //bind events
         for (var i = 0; i < e.length; i += 1) {
             ele.addEventListener(e[i], h, c);
         }
     },
     initz: function() {
         this.listenz(document.getElementById("real"), ["change"], this, false);
         this.listenz(document.getElementById("foi"), ["change"], this, false);
         this.listenz(document.getElementById("sim"), ["change"], this, false);
         this.listenz(document.getElementById("rev"), ["change"], this, false);
     },

     handleEvent: function(e) {
         switch (e.target.id) {
             case 'real':
                 console.log('real');
                 //this.realtime = e.target.checked ? true : false;
                 //this.realz();
                 //if (this.realtime) this.submitz();
                 break;
             default:
                 console.log('default');
                 //if (this.realtime) this.submitz();
                 break;
         }
     }
 };

HTML

<body>
    <div class="wrapper">
        <ul>
            <li>
                Real
                <input type="checkbox" name="real" id="real">
            </li>
            <li>
                Strip
                <input type="checkbox" name="sim" id="sim">
            </li>
            <li>
                Reverse
                <input type="checkbox" name="rev" id="rev">
            </li>
            <li>
                Foil
                <input type="checkbox" name="foi" id="foi">
            </li>
        </ul>
    </div>
    <script>
        controller.initz();
    </script>
</body>

【问题讨论】:

  • c 应该是回调函数,这里传递this。显然,this 不是一个函数。在你的initz 函数中,我想你想要this.listenz(yourElement, ["change"], handleEvent, false);
  • @Kaiido 如果我使用 this.handleEvent,它会告诉我事件未定义,特别是“无法读取未定义的属性‘目标’”。有什么想法吗?
  • 知道为什么我的小提琴不起作用吗? jsfiddle.net/incept0/rn7rx6fr/2
  • 您的控制器从未启动过,h 应该是h: function(){fn.apply(this, o &amp;&amp; o instanceof Array ? o : arguments); };updated fiddle
  • @Kaiido 您能否修改小提琴以反映您的意思。当前在 listenz 函数中的 h 函数。您是说将其取出并使其成为控制器对象的方法吗?我怎么称呼它?

标签: javascript html dom javascript-objects addeventlistener


【解决方案1】:

几个问题:

  • listenz 函数的fn 参数实际上代表function 并等待回调。在这里,在您的listenz 函数中,您传递的是this,它是controller 对象。将其更改为this.handleEvent

  • h 变量将默认事件参数覆盖为listenz 函数中o 参数中指定的参数(如果有)。就像现在写的那样,如果没有指定o 参数,它将向回调函数应用一个空数组。您想要的是应用默认参数,因此您应该将其更改为

     var h = function() {
        fn.apply(this, o && o instanceof Array ? o : arguments);
     }  
    

最后,您永远不会启动控制器对象。

这是一个有效的 sn-p :

     var controller = {

         realtime: true,
         listenz: function(ele, e, fn, c, o) {

             //validate
             if (!(e instanceof Array)) {
                 throw 'Javascript Listener:  Error 642';
             }


             var h = function() {
             	fn.apply(this, o && o instanceof Array ? o : arguments);
             };


             //bind events
             for (var i = 0; i < e.length; i ++) {
                 ele.addEventListener(e[i], h, c);
             }
         },
         initz: function() {
             this.listenz(document.getElementById("real"), ["change"], this.handleEvent, false);
             this.listenz(document.getElementById("foi"), ["change"], this.handleEvent, false);
             this.listenz(document.getElementById("sim"), ["change"], this.handleEvent, false);
             this.listenz(document.getElementById("rev"), ["change"], this.handleEvent, false);
         },

         handleEvent: function(e) {
             switch (e.target.id) {
                 case 'real':
                     alert('real');
                 	 
                     //this.realtime = e.target.checked ? true : false;
                     //this.realz();
                     if (this.realtime) this.submitz();
                     break;
                 default:
                     console.log('default');
                     if (this.realtime) this.submitz();
                     break;
             }
         }
     };
controller.initz()
	<body>
	    <div class="wrapper">
	        <ul>
	            <li>
	                Real
	                <input type="checkbox" name="real" id="real">
	            </li>
	            <li>
	                Strip
	                <input type="checkbox" name="sim" id="sim">
	            </li>
	            <li>
	                Reverse
	                <input type="checkbox" name="rev" id="rev">
	            </li>
	            <li>
	                Foil
	                <input type="checkbox" name="foi" id="foi">
	            </li>
	        </ul>
	    </div>
	   
	</body>

【讨论】:

  • 感谢您的帮助。注意:控制器对象实际上是在 html 中在 body 的结束标记之前初始化的。
  • @NotoriousPet0 不客气,关于controller.initz 它不在你的小提琴中,我在你的代码示例中错过了它。如果您没有看到任何反对意见,我会留在这里
  • 当然,没有异议,你是对的,我没有把它放在小提琴中,因为我没有意识到它应该放在 javascript 部分。所以你也帮我弄清楚了。再次感谢您的帮助。
  • 哦,不过要小心,你必须在元素被解析后调用'controler.initz()'。因此,要么你按照你在问题的 sn-p 中所做的那样做,要么将整个事情包装在一个 onload 事件处理程序中(这是推荐的方式和 jsfiddle 的默认方式)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-21
  • 1970-01-01
相关资源
最近更新 更多