gpt4 book ai didi

javascript - 如何在委托(delegate)的事件监听器中支持 stopPropagation

转载 作者:行者123 更新时间:2023-11-30 19:23:06 25 4
gpt4 key购买 nike

我查看了 jQuery 的源代码,以了解它们如何在委托(delegate)事件监听器中实现对 event.stopPropagation() 的支持,即 document.on(event, element. ..),但似乎无法让我自己的 vanilla JS 实现完全工作。

我尝试在我的方法中覆盖 native event.stopPropagation() 以简单地在事件本身上设置一个 event.propagationStopped ,并在决定是否事件应该传播到它的 parent 。

当停止传播的事件监听器附加在其他事件监听器之前时,这会起作用,但是当它以相反的顺序附加时它不会,这在 jQuery 的实现中确实按预期工作。

function delegate(type, selector, callback) {
document.addEventListener(type, function(event) {
event.stopPropagation = function() {
event.propagationStopped = true;
};

var element = event.target, found;

while (element && element.parentNode) {
if (element.matches(selector)) {
callback.call(element, event);
}

if (!event.propagationStopped) {
element = element.parentNode;
} else {
break;
}
}
});
}


delegate('click', '.overlay', function() {
console.log('Close overlay');
});

delegate('click', '.modal', function(e) {
e.stopPropagation();

console.log('Clicked inside modal, stopping propagation...');
});

我希望事件停止在所有事件监听器中的进一步传播,而不管它们的附加顺序如何,而不是当前的行为。

最佳答案

我认为这只能通过在单个事件监听器中自己进行委托(delegate)事件传播来实现。在您当前的实现中,附加到 document 的第二个监听器总是第二个触发,无论其选择器如何 - 但当它选择另一个选择器的后代时,您需要它首先触发。

在这里,我收集了一个委托(delegate)事件监听器列表,然后针对父遍历中的每个元素对其进行迭代。您可以将列表保留在元素本身上(例如,使用符号或 WeakMap),但由于您只委托(delegate) document,我将简单地将它们存储在全局范围内。

const delegatedListeners = {};

function delegate(type, selector, callback) {
if (!delegatedListeners[type]) {
const listeners = delegatedListeners[type] = [];
document.addEventListener(type, function(event) {
for (let element = event.target; element && element.parentNode; element = element.parentNode) {
// unfortunately, event.currentTarget cannot be overwritten with element
for (const {selector, callback} of listeners) {
if (element.matches(selector)) {
callback.call(element, event);
}
}
if (event.cancelBubble) { // a getter for the propagation stopped flag :-)
break;
}
}
});
}
delegatedListeners[type].push({selector, callback});
}

关于javascript - 如何在委托(delegate)的事件监听器中支持 stopPropagation,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57245006/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com