这是一个有效的例子:
$(document).on("input propertychange", ".myClass", function () {
$('#result').append("first<br />");
});
$('.myClass').on("input propertychange", function () {
$('#result').append("second<br />");
});
Run Code Online (Sandbox Code Playgroud)
即使我在first之前定义代码块second,它总是second先打印.
为什么?我怎样才能保证它们会以级联方式执行?
因为这是事件处理的工作方式.事件首先经历从窗口到文档到目标元素的捕获阶段,然后从目标元素冒泡到窗口.
你的第一个on调用附加一个click处理程序document,当被调用时,将检查事件是否通过.myClass最终目标之间匹配的任何元素document,如果是,则调用你的处理程序.您的第二个on调用将处理程序直接附加到匹配元素.在这两种情况下,你都在挂钩冒泡阶段(jQuery不支持挂钩捕获阶段).因此,在文档上匹配的委托处理程序之前调用元素本身的处理程序.(从技术上讲,当事件位于目标元素时,它处于目标阶段,而不是捕获或冒泡.但是捕获和冒泡处理程序都会在目标元素上按顺序进行处理.)
这是旧DOM3事件规范的一个很好的一体化图表:
您可以在当前的DOM4规范中找到详细信息.
虽然jQuery不支持捕获阶段,但是addEventListener在兼容的浏览器上(因此,不是IE8和更早版本,没有捕获或addEventListener).第三个参数addEventListener让你决定是否需要capture(true)或bubbling(false); 它默认为false(在真正的现代系统中,第三个参数可以是具有各种标志的对象).
这是一个显示所有阶段中的事件的示例:
// See: https://www.w3.org/TR/domcore/#dom-event-none
const eventPhases = ["NONE", "CAPTURING_PHASE", "AT_TARGET", "BUBBLING_PHASE"];
function captureHandler(e) {
console.log("captureHandler: " + eventPhases[e.eventPhase] + " on " + this.id);
}
function bubbleHandler(e) {
console.log("bubbleHandler: " + eventPhases[e.eventPhase] + " on " + this.id);
}
function hookBoth(element) {
element.addEventListener("click", captureHandler, true);
element.addEventListener("click", bubbleHandler, false);
}
hookBoth(document.getElementById("outer"));
hookBoth(document.getElementById("middle"));
hookBoth(document.getElementById("target"));Run Code Online (Sandbox Code Playgroud)
<div id="outer">
<div id="middle">
<div id="target">Click Me</div>
</div>
</div>Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
61 次 |
| 最近记录: |