【问题标题】:How to chain addEventListener?如何链接 addEventListener?
【发布时间】:2021-11-03 21:33:18
【问题描述】:

我有以下代码:

document.querySelector('.mySelector').addEventListener("mouseover", function() {
    this.parentNode.parentNode.classList.add("over");
});
document.querySelector('.mySelector').addEventListener("mouseout", function(){
    this.parentNode.parentNode.classList.remove("over");
});

鉴于这两个事件在同一个目标上,有没有办法像这样链接两个addEventListener 方法? :

document.querySelector('.mySelector').addEventListener("mouseover", function() {
    this.parentNode.parentNode.classList.add("over");
}).addEventListener("mouseout", function(){
    this.parentNode.parentNode.classList.remove("over");
});

这样做会产生错误:

未捕获的类型错误:无法读取属性“addEventListener” 未定义

【问题讨论】:

    标签: javascript addeventlistener


    【解决方案1】:

    链接addEventListener 是不可能的,因为该方法不返回任何东西(它实际上确实返回undefined)。 specification 指定为:

     interface EventTarget {
      void               addEventListener(in DOMString type, 
                                          in EventListener listener, 
                                          in boolean useCapture);
    

    当然,您可以将 addEventListener 替换为您自己的实现:

    EventTarget.prototype.addEventListener = (() => {
      const addEventListener = EventTarget.prototype.addEventListener;
      return function() {
        addEventListener.apply(this, arguments);
        return this;
      };
    })();
    
    document.querySelector('button').addEventListener('hover', () => {
       console.log('hover');
    }).addEventListener('click', () => {
       console.log('click');
    });
    

    但经常建议不要使用内置原型,因为它可能会产生不必要的副作用。

    【讨论】:

      【解决方案2】:

      这是我用于项目的基本事件链函数。这并不花哨,但它允许链接事件并根据需要使用单个函数来处理所有事件类型。

      基本 html 为 MouseMove 类型添加了事件处理程序,但应该适用于其他事件类型。

      为了链接事件,您的函数需要在末尾有一个“return”,它将返回到调用 eventHandler 并链接到列表中的下一个函数。

      <body>
              <div id="canvas" onmousemove="eventHandler(event)"></div>
      </body>
      
      // Call to add event handler to chain
      addEventHandler(eventHandler1);
      
      // Call to remove event handler from chain
      removeEventHandler(eventHandler1);
      
      
      var mMoveEventList = new Array();
      
      function addEventHandler(eventHandler) {
          mMoveEventList.push(eventHandler);
      }
      
      function removeEventHandler(eventHandler) {
          mMoveEventList.splice(mMoveEventList.indexOf(eventHandler));
      }
      
      function eventHandler1(e) {
          console.log("EventHandler1")
          return;  // REQUIRED TO RETURN TO EVENTHANDLER
      }
      
      function eventHandler2(e) {
          console.log("EventHandler2")
          return;  // REQUIRED TO RETURN TO EVENTHANDLER 
      }
      
      function eventHandler(e) {
          switch (e.type) {
              case "mousemove":
                  console.log("mouseMoveEvent");
      
                  if (mMoveEventList.length > 0) {
                      for (let i = 0; i < mMoveEventList.length; index++) {
                          mMoveEventList[i]();
                      }
                  }
                  break;
              default:
                  # Other event types can be added here
                  console.log("Event:", e.type);
                  break;
              }
          }
      }
      

      【讨论】:

        【解决方案3】:

        EventTarget.addEventListener() 不返回调用它的对象,这意味着它不能被链接。

        所以你必须使用某种包装器来做到这一点,例如使用JQuery.on():

        $('.mySelector')
         .on("mouseover",function() {...})
         .on("mouseout",function() {...})
        

        【讨论】:

          猜你喜欢
          • 2020-12-09
          • 1970-01-01
          • 1970-01-01
          • 2012-05-25
          • 1970-01-01
          • 2010-09-08
          • 2011-11-22
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多