一个文档中有2个脚本

// 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)怎么办?

最佳答案



如果您可以先注册处理程序,则可以先进行注册,前提是您使用的浏览器正确实现了DOM3事件(除非是IE8或更早版本,否则它可能会这样做)。

这里至少涉及四件事:

  • 防止默认设置。
  • 停止传播到祖先元素。
  • 停止调用同一元素上的其他处理程序。
  • 调用处理程序的顺序。

  • 为了:

    1.防止默认

    这就是DOM0处理程序中的return false所做的。 (详细信息:The Story on Return False。)DOM2和DOM3中的等效项是 preventDefault :
    document.addEventListener("click", function(e) {
        e.preventDefault();
    }, false);
    

    防止默认设置可能与您正在执行的操作无关,但是由于您在DOM0处理程序中使用了return false,并且可以防止默认设置,因此为了完整起见,此处将其包括在内。

    2.停止传播到祖先元素

    DOM0处理程序无法执行此操作。 DOM2通过 stopPropagation 做到了:
    document.addEventListener("click", function(e) {
        e.stopPropagation();
    }, false);
    

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



    (我的重点。)

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

    自然地,对于DOM0来说并没有出现这种情况,因为在同一元素上不可能有相同事件的其他处理程序。 :-)

    据我所知,在DOM2中无法做到这一点,但是DOM3为我们提供了 stopImmediatePropagation :
    document.addEventListener("click", function(e) {
        e.stopImmediatePropagation();
    }, false);
    

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

    4.调用处理程序的顺序

    再说一次,没有与DOM0相关的东西,因为不可能有其他处理程序。

    在DOM2中,规范明确指出不能保证调用附加到元素的处理程序的顺序。但是DOM3改变了这一点,说处理程序是按照注册时的顺序调用的。

    首先,从DOM2 Section 1.2.1:



    但这被DOM3 Section 3.1取代:



    (我的重点。)

    如果您将事件与库连接起来,则某些库可以保证顺序。

    还值得注意的是,在Microsoft DOM2的前身(例如attachEvent)中,它与DOM3的顺序相反:处理程序以相反的注册顺序调用。

    因此,将#3和#4放在一起,如果可以先注册您的处理程序,则会首先调用它,并且可以使用stopImmediatePropagation防止其他处理程序被调用。只要浏览器正确实现DOM3。

    所有这一切(包括IE8和更早版本甚至都没有实现DOM2事件,更不用说DOM3的事实)是人们使用jQuery之类的库的原因之一,其中某些库确实保证了顺序(只要一切都通过钩住处理程序即可)库),并提供了一些方法来停止调用同一元素上的其他处理程序。 (例如,使用jQuery时,顺序就是它们附加的顺序,您可以使用stopImmediatePropagation停止对其他处理程序的调用。但是我并不想在这里出售jQuery,只是在解释一些库提供了比基本的DOM内容。)

    07-28 00:53