将addEventListener添加到除一个元素以外的所有元素

7

我试图放弃使用jQuery(我的心态是正确的,对吧?),但我遇到了一些问题,无法获得与:not()选择器相当的东西。

我有一个document.body.addEventListener("mousewheel", scrollTriggered),我希望它在除特定div(在fiddle中为#something)之外的任何滚动时触发。我尝试整合event.target,但没有成功。

非常感谢任何帮助。 请参见JSFiddle

4个回答

13

最简单的方法可能是使用第三个参数设置为falseaddEventListener执行指定操作,然后在要排除的元素上再添加另一个addEventListener,将第三个参数设置为true,这将取消事件传播到其他事件监听器。第三个参数有点复杂,但重要的是,如果它设置为true,则该监听器将在任何false处理程序之前触发。正如@FelixKling所说,实际上在此处不需要将其设置为true,但是在需要处理程序在另一个处理程序之前触发时,这样做是一个好习惯,因为有时确实需要。这里是一个jsfiddle示例:http://jsfiddle.net/markasoftware/sBg3a/2/

document.body.addEventListener("mousewheel", scrollTriggered,false);

function scrollTriggered() {
    console.log('hi');
}

document.getElementById('something').addEventListener('mousewheel',function(e) {
    e.stopPropagation();
}, true);

虽然 @FelixKling 的答案是可行的,但我个人认为这种方法更加优雅,并且通常会使用类似这样的方式而不是其他方式。我喜欢主事件侦听器只有侦听器代码的方式,而所有取消事件传播的内容可以完全分开,使其更加不显眼。


好主意,但我认为在捕获阶段绑定处理程序并不是必要的,你也可以在冒泡阶段绑定它。 - Felix Kling
是的,我想现在想想,我只是习惯了在想让处理程序在另一个处理程序之前触发时使用捕获阶段,这只是出于良好的实践。 - markasoftware

13

您可以检查事件是否来自于要避免的元素内部。为此,您需要从target向上遍历DOM树,并比较每个节点的id属性,或使用Node.contains(但先检查兼容性部分):

var ignore = document.getElementById('something');

function scrollTriggered(event) {
    var target = event.target;
    if (target === ignore || ignore.contains(target)) {
        return;
    }
    // do other stuff
}

演示


话虽如此,Markasoftware的回答更好,因为它从一开始就防止了事件。


2
谢谢你提到了我!:D - markasoftware

3
您可以在事件处理程序中检查目标元素,如果该目标元素具有id为“something”,则返回false。
像这样:
function scrollTriggered (event) {
    if (event.target.id === "something") {
      // don't do anything
       return;
    } else {
       // do something  
    }
 }

不一定有效,因为它可能会从“something”元素内部的一个元素冒泡并使其无法工作。@FelixKling的答案可能是一个更好的想法。 - markasoftware

0

您可以使用EcmaScript 6的下一个示例代码:

function scrollTriggered(event) {
    var target = event.target;
    if (target.outerHTML.includes('something')) { 
        return;
    }
    // do other stuff
}

我们从HTML元素中提取字符串,并尝试在其中找到某些内容。如果您位于需要忽略的必要元素内部,则此方法将起作用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接