【问题标题】:Event listener for current and future elements Without jQuery当前和未来元素的事件监听器没有 jQuery
【发布时间】:2016-02-27 03:52:47
【问题描述】:

如果我没记错的话,我曾经见过一种方法,可以将事件侦听器绑定到与特定条件匹配的每个元素,可能是查询选择器。再次寻找它,除了高度依赖 jQuery 的人之外,我找不到其他任何东西,但我更喜欢一种真正简单的方法来实现这一点。

有人知道这个方法叫什么吗?

【问题讨论】:

标签: javascript dom-events web-standards


【解决方案1】:

我写了一个更通用的函数,它接受一个选择器、事件类型和一个处理函数,类似于 jQuery 的 on 函数:

/** adds a live event handler akin to jQuery's on() */
function addLiveEventListeners(selector, event, handler){
    document.querySelector("body").addEventListener(
         event
        ,function(evt){
            var target = evt.target;
            while (target != null){
                var isMatch = target.matches(selector);
                if (isMatch){
                    handler(evt);
                    return;
                }
                target = target.parentElement;
            }
        }
        ,true
    );
}

例如,对 div 的任何点击都会调用以下命令,即使它是在以后添加到 DOM 中的:

addLiveEventListeners("div", "click", function(evt){ console.log(evt); });

这适用于所有现代浏览器和 Microsoft Edge。为了让它在 IE9 中工作 -- IE11 测试 target.matches(selector) 应该像这样修改:

var isMatch = target.matches ? target.matches(selector) : target.msMatchesSelector(selector);

然后测试if (isMatch) 也适用于这些浏览器。

另请参阅我对 Adding event listeners to multiple elements 的回答,它将事件侦听器添加到元素本身而不是 body

【讨论】:

  • 这个答案可能有点老了,但是您可以通过以下方式替换对处理程序的调用来进一步模仿 jQuery 的“on”方法:handler.call(target, evt); 这样您可以获得与this 相同的行为指的是根据您的选择器触发事件​​的元素,而您仍然在事件的属性中获取原始目标。
【解决方案2】:

您正在寻找的方法称为事件捕获。你可以这样做:

document.querySelector('body').addEventListener('click', function(evt) {
    // Do some check on target
    if ( evt.target.classList.contains('some-class') ) {
        // DO CODE
    }
}, true); // Use Capturing

【讨论】:

  • 我记得我看到的有点复杂,但我认为您的解决方案会运作良好,所以我选择了它,而没有更好的办法出现。谢谢。
  • 那么,如果我点击子元素,“捕获”部分将确保它能够工作?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-17
  • 2022-01-17
  • 2017-04-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多