Я просмотрел исходный код из jQuery, чтобы узнать, как они реализовали поддержку event.stopPropagation()
в делегированных прослушивателях событий, то есть document.on(event, element...)
, но, похоже, не могу заставить мою собственную ванильную реализацию JS полностью работать.
Я попытался переопределить собственный event.stopPropagation()
в своем методе, чтобы просто установить event.propagationStopped
для самого события и искать это при принятии решения о том, должно ли событие распространяться на своих родителей.
Это работает, когда прослушиватель событий, который останавливает распространение, подключается раньше других, однако это не работает, когда он подключается в обратном порядке, что работает, как и ожидалось, в реализации 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...');
});
Я хочу, чтобы событие прекратило свое дальнейшее распространение во всех прослушивателях событий независимо от порядка, в котором они были прикреплены, вместо текущего поведения.