代码之家  ›  专栏  ›  技术社区  ›  Jens Törnell

检查事件侦听器与javascript的冲突[重复]

  •  0
  • Jens Törnell  · 技术社区  · 7 年前

    文档中有两个脚本

    // my_script.js goes first
    document.onclick = function() {
        alert("document clicked");
    };
    
    // other_script.js comes after
    // this overrides the onclick of my script,
    // and alert will NOT be fired
    document.onclick = function() {
        return false;
    };
    

    为了确保我的click事件不会被其他脚本覆盖,我切换到 addEventListener .

    // my_script.js goes first
    document.addEventListener("click", function() {
        alert("document clicked");
    }, false);
    
    // other_script.js comes after
    document.addEventListener("click", function() {
        return false;
    }, false);
    

    现在我有另一个问题。自从 return false 在第二个代码中定义 alert ,为什么不阻止调用警报?

    如果我想让我的脚本完全控制click事件(比如一直返回false而忽略其他脚本中定义的事件),该怎么办?

    0 回复  |  直到 13 年前
        1
  •  46
  •   T.J. Crowder    13 年前

    如果我想让我的脚本完全控制click事件(比如一直返回false而忽略其他脚本中定义的事件),该怎么办?

    如果您可以先注册处理程序,那么在注册之前,只要您使用的浏览器正确地实现了dom3事件(除非是ie8或更早版本,否则它可能会实现)。

    这里至少涉及四件事:

    1. 防止违约。

    2. 停止传播到祖先元素。

    3. 停止上的其他处理程序 相同的 元素被调用。

    4. 调用处理程序的顺序。

    整齐:

    1。防止违约

    这是什么 return false 从dom0处理程序执行。(详情: The Story on Return False )DOM2和DOM3中的等效值为 preventDefault :

    document.addEventListener("click", function(e) {
        e.preventDefault();
    }, false);
    

    防止违约可能与您正在做的事情无关,但因为您正在使用 返回假 在您的dom0处理程序中,这防止了默认值,为了完整起见,我将其包含在这里。

    2。停止传播到祖先元素

    dom0处理程序无法执行此操作。DOM2一个可以,通过 stopPropagation :

    document.addEventListener("click", function(e) {
        e.stopPropagation();
    }, false);
    

    但是 停止传播 不会停止调用同一元素上的其他处理程序。从 the spec :

    这个 停止传播 方法用于防止事件流期间事件的进一步传播。如果此方法被任何 EventListener 事件将停止在树中传播。 事件将完成对当前 EventTarget 在事件流停止之前。

    (我的重点。)

    三。停止上的其他处理程序 相同的 被调用的元素

    当然,dom0不会出现这种情况,因为 同一元素上同一事件的其他处理程序。-)

    据我所知,在dom2中没有办法这样做,但是dom3给了我们 stopImmediatePropagation :

    document.addEventListener("click", function(e) {
        e.stopImmediatePropagation();
    }, false);
    

    一些库为通过库连接的处理程序提供此功能(甚至在非dom3系统(如ie8)上),请参见下文。

    4。调用处理程序的顺序

    同样,与dom0无关,因为不可能有其他处理程序。

    在dom2中,规范 明确地 表示不保证调用附加到元素的处理程序的顺序;但是dom3改变了这个顺序,表示处理程序是按照它们注册的顺序调用的。

    首先,来自DOM2 Section 1.2.1 :

    虽然所有 EventListeners 事件目标 保证会被它接收到的任何事件触发 事件目标 ,没有说明他们接收另一个事件的顺序。 事件侦听器 事件目标 .

    但这已经被DOM3取代了 Section 3.1 :

    接下来,实现必须确定当前目标的候选事件侦听器。这必须是在当前目标上注册的所有事件侦听器的列表 按注册顺序 .

    (我的重点。)

    如果您将事件与库挂钩,则某些库可以保证顺序。

    值得注意的是,在微软dom2的前身中(例如, attachEvent ,这与dom3的顺序相反:调用了处理程序 颠倒 登记顺序。


    所以把3和4放在一起,如果你可以先注册你的处理程序,它将首先被调用,你可以使用 停止立即传播 以防止其他处理程序被调用。前提是浏览器正确地实现了dom3。


    所有这些(包括ie8和更早版本甚至都没有实现dom2事件,更不用说dom3)是人们使用jquery等库的原因之一,其中一些确实保证了顺序(只要所有东西都通过相关的库连接它们的处理程序),并且提供了一些方法来阻止同一个元素上的其他处理程序被调用。(例如,对于jquery,order是它们附加的顺序,您可以使用 停止立即传播 停止对其他处理程序的调用。但我并不是想在这里销售jquery,只是解释一些lib提供的功能比基本的dom提供的功能要多。)