我想将项目中的代码从 jQuery.on
转换为 .addEventListener
并删除对 jQuery 的依赖。
主要问题:有没有一种方法可以用相对较少的代码来完成此操作,或者我是否需要编写像 jQuery 那样的自定义事件处理?
------------------------------------------
| a |
| |
| ----------------------------- |
| | b | |
| | | |
| | --------------- | |
| | | c | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | --------------- | |
| | | |
| | | |
| ----------------------------- |
| |
| |
------------------------------------------
点击c应该返回c的处理程序,然后是b,然后是a
我已经阅读了多个 stackoverflow 问题*和答案,它们让我对两者之间的差异(或者主要是 jQuery 添加的附加逻辑)有了基本的了解。在此fiddle您可以查看一个基本示例,我希望以 jQuery 的方式工作。
我很清楚,当事件从目标 (div.c
) 冒出时,它会到达 div.a
,然后到达 div 上的监听器.a
按照它们添加的顺序被触发,在本例中结果是 a、b、c,而不是像 jQuery 那样的 c、b、a。
b 是粗体,因为它不会被触发,尽管这应该是期望的行为。
它没有被触发的原因是 e.target (div.c
) 与 querySelector .b
不匹配。
对我来说,当事件从 .addEventHandler
触发时,jQuery 使用自己的事件句柄/触发。
尽管监听器是从公共(public)父级触发的,但似乎还是考虑了 DOM 嵌套。
考虑 DOM 嵌套的最后一部分是我希望使用“vanilla”js 实现的。
使用 $._data(element, 'events')
我们可以访问 jQuery 内部存储的事件来查看它们。
这里的guid
属性似乎表明了事件被触发的顺序。
但是我无法找到如何确定/触发订单。
非常感谢任何帮助!
*
相关问题
jQuery .on(); vs JavaScript .addEventListener();
jQuery event handlers always execute in order they were bound - any way around this?
最佳答案
您可以遍历目标的所有祖先并检查它们是否与特定选择器匹配,并为每个匹配实例调用回调
它们触发的顺序仍然是它们添加到根元素的顺序
HTMLElement.prototype.delegate = function(evtName, selector, callback) {
var rootElement = this;
this.addEventListener(evtName, function(e) {
var matchingAncestors = [], parent = e.target.parentElement;
// TODO: Abort if target is root element
if (e.target.matches(selector)) {
console.log('selector', selector,'matches target')
callback(e)
} else {
// we know it's not the target so work way up ancestors finding selector matches
while (parent && parent !== rootElement) {
if (parent.matches(selector)) {
matchingAncestors.push(parent)
}
parent = parent.parentElement
}
// call the callback for each instance
matchingAncestors.forEach(function(el) {
console.log(el, ' is matching ancestor of target')
callback(e)
});
}
})
}
var a = document.querySelector(".a");
a.addEventListener("click", function(e) {
console.log('*********************************')
console.log("Vanilla a\n");
});
a.delegate('click', '.b', function(e) {
console.log("Vanilla-delegate b\n");
})
a.delegate('click', '.c', function(e) {
console.log("Vanilla-delegate c\n");
})
div {padding-left:30px; border:1px solid #ccc}
<div class="a">
a
<div class="b">
b
<div class="c">
c<br>(click me)
</div>
</div>
</div>
请注意,这在生产中未经测试
关于javascript - 将 jQuery.on(event,selector,func) 转换为 .addEventListener(event, func) 特别是 DOM 树后面的选择器部分和事件气泡,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51351646/