原生JS相当于jQuery委托
Native JS equivalent to jQuery delegation
动态创建的dom元素上的事件委托的本地实现是什么?
我试着看jQuery源代码,但我不能遵循.on
方法。
注意:目前我附加的事件处理程序后的dom元素创建,这似乎很标准,但我喜欢的方式,jQuery .on
处理动态创建的元素事件与此语法$( document ).on( "click", ".selector", handler );
基本上是这样的:
// $(document).on("click", <selector>, handler)
document.addEventListener("click", function(e) {
for (var target=e.target; target && target!=this; target=target.parentNode) {
// loop parent nodes from the target to the delegation node
if (target.matches(<selector>)) {
handler.call(target, e);
break;
}
}
}, false);
然而,当handler
被调用时,e.currentTarget
是document
,而e.stop[Immediate]Propagation()
的工作方式不同。jQuery对其进行了大量抽象(包括调用顺序)。
我使用了.matches()
方法,它还不是标准的,但在现代浏览器中已经可以使用不同的名称。您可以使用自定义谓词来测试元素,而不是使用选择器。而addEventListener
显然不兼容oldie。
对于普通的HTML元素,这应该可以帮你完成:
HTMLElement.prototype.on = function(event, selector, handler) {
this.addEventListener(event, function(e) {
let target = e.target;
if (typeof(selector) === 'string') {
while (!target.matches(selector) && target !== this) {
target = target.parentElement;
}
if (target.matches(selector))
handler.call(target, e);
} else {
selector.call(this, e);
}
});
};
即使不遍历事件目标的所有祖先,也可以实现事件委托。
$(document).on("click", selector, handler);
可以在NativeJS中写成:
document.addEventListener("click", event => {
var el = document.querySelector(selector);
if (el && el.contains(event.target)) {
handler.call(el, event);
}
});
想玩代码高尔夫;)
108字节(基于@Bergi)
(e,d,g,h,b)=>e.addEventListener(d,c=>{for(d=e,b=c.target;b!=d;)b.matches(g)?h.call(d=b,c,b):b=b.parentNode})
工作演示:
window.$on = (e,d,g,h,b)=>e.addEventListener(d,c=>{for(d=e,b=c.target;b!=d;)b.matches(g)?h.call(d=b,c,b):b=b.parentNode})
$on(document.body, 'click', '.clickable', (evt, matched) => {
console.log(matched)
})
<div class="wrapper">
<div class="not-clickable rect">
not clickable
</div>
<div class="clickable rect">
clickable
</div>
<div class="clickable rect">
clickable
<div class="child">child element</div>
</div>
</div>
<style>
.rect {
width: 100px;
height: 100px;
background: red;
border: 1px solid;
margin: 10px;
float: left;
}
.child {
background: gray;
}
</style>
代替这个JQuery
$(document).on('click', '.your-selector', function() {
// do something
});
我经常在纯javascript中使用
document.addEventListener('click', function(e) {
// e.target can be a sub element of the one we want
const el = e.target ? e.target.closest('.your-selector') : null;
if (el) {
// do something
}
});
提示:"closest"在javascript中首先包含元素本身,然后开始在DOM
例如,我们有这样一个html结构。
<ul>
<li>
item 1
<button class="btn-edit"><i class="fas fa-pencil"></i></button>
</li>
<li>
item 3
<button class="btn-edit"><i class="fas fa-pencil"></i></button>
</li>
<li>
item 3
<button class="btn-edit"><i class="fas fa-pencil"></i></button>
</li>
</ul>
请注意,按钮内部有一个i标记。
如果您想为Click事件准确捕获正确的项,您需要如下所示的函数。
function delegateClick(selector, callback){
let selectorItems = document.querySelectorAll(selector);
document.addEventListener('click', function(e){
let clickedItems = e.path;
for(let clickedItem of clickedItems){
for(let selectorItem of selectorItems){
if(clickedItem === selectorItem){
callback(clickedItem);
}
}
}
});
}
这提供了与jquery非常相似的用法。
delegateClick('.btn-edit', (elm) => {
//access the clicked DOM element
elm;
});
相关文章:
- 如何使用我的Jquery代码创建委托事件侦听器
- 如何使用jquery委托方法
- Jquery:更改下拉列表的值.通过委托事件触发时
- Jquery 委托方法应用程序
- jQuery两个不同的委托
- 如何在jquery中使用单个取消删除方法删除多个事件委托
- 为什么我的 jQuery 委托点击会多次触发
- jQuery 插件中的事件委托
- 如何使用 jquery 事件委托时获取最后一个事件
- 如何将单击事件委托给 jQuery 元素数组的子级
- jQuery委托事件方法对网格的好处
- 如果在 jQuery 委托事件处理程序中更改了 AngularJS 模型,它不会立即更新
- Jquery - 委托多个元素和多个事件
- 使用委托绑定 jquery 对象时访问它
- jQuery 委托加载新创建元素的事件处理程序
- Jquery 委托事件仅在两个选择器之一上工作
- 使委托的 jQuery 自动完成
- jQuery 1.7 .on() 事件委托不适用于禁用元素上的选择器
- 使用委托JQUERY时,JQUERY事件多次触发
- 直接vs.委托- jQuery .on()