对象方法内的多个事件侦听器 Javascript HTML DOM

Multiple Event Listeners inside of Object Method Javascript HTML DOM

这里有一些答案和我通过 google 发现的一些东西,它们几乎让我到达了我想去的地方,但有些东西告诉我我做错了,希望能得到一些帮助。

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

我目前遇到的错误是在 listenz() 方法中抛出的,并告诉我 "fn is not a function"。我猜这是有道理的,它是一个对象,但我该如何解决它?

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>

几个问题:

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

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

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

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

这是一个工作片段:

     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>