我想将项目中的代码从jQuery.on
转换为.addEventListener
,并消除对jQuery的依赖。
主要问题:有没有办法用相对较少的代码来做到这一点,还是我需要编写一个自定义事件处理程序(如jQuery似乎有的?)?
------------------------------------------
| a |
| |
| ----------------------------- |
| | b | |
| | | |
| | --------------- | |
| | | c | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | --------------- | |
| | | |
| | | |
| ----------------------------- |
| |
| |
------------------------------------------
点击 c ,应返回 c 的处理程序,然后依次是 b 和 a
我已经阅读了多个stackoverflow问题*和答案,这使我对两者之间的区别有一个基本的了解(或者主要是jQuery添加的附加逻辑)。在此fiddle中,您可以看到一个我想以jQuery工作方式工作的基本示例。
我很清楚,当事件从目标(div.c
)起泡时,事件到达div.a
,然后div.a
上的侦听器按添加顺序被触发,在此示例中,结果是 b ,c而不是c,b,类似于jQuery。
b 为粗体,因为尽管这是期望的行为,但它不会被触发。
之所以不会被触发,是因为e.target(div.c
)与querySelector .b
不匹配。
在我看来,当从.addEventHandler
触发事件时,jQuery会使用自己的事件处理/触发。
而且,即使侦听器是从公共父级触发的,似乎也要考虑到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?
答案 0 :(得分:1)
您可以遍历目标的所有祖先,并检查它们是否与特定选择器匹配,并为每个匹配的实例调用回调
它们触发的顺序仍然是它们添加到根元素的顺序
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>
请注意,这未经生产测试