Javascript 本机JS相当于jQuery委托

Javascript 本机JS相当于jQuery委托,javascript,dom,dom-events,event-delegation,Javascript,Dom,Dom Events,Event Delegation,动态创建的dom元素上的事件委派的本机实现是什么 我试图查看jQuery源代码,但无法遵循方法上的 注意:目前,我在创建dom元素后附加事件处理程序,这似乎很标准,但我喜欢jQuery.on使用此语法处理动态创建的元素事件(document)发生的基本情况是: // $(document).on("click", <selector>, handler) document.addEventListener("click", function(e) { for (var tar

动态创建的dom元素上的事件委派的本机实现是什么

我试图查看jQuery源代码,但无法遵循方法上的


注意:目前,我在创建dom元素后附加事件处理程序,这似乎很标准,但我喜欢jQuery
.on
使用此语法处理动态创建的元素事件(document)

发生的基本情况是:

// $(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);
/$(文档)。打开(“单击”,处理程序)
文档.添加的列表器(“单击”,函数(e){
for(var target=e.target;target&&target!=this;target=target.parentNode){
//将父节点从目标循环到委派节点
if(target.matches()){
调用(target,e);
打破
}
}
},假);
但是,调用
处理程序时,
e.currentTarget
文档
,而
e.stop[Immediate]Propagation()
的工作方式不同。jQuery对此(包括调用顺序)进行了大量抽象


我使用了,它还不是标准的,但在现代浏览器中已经有了不同的名称。您可以使用自定义谓词而不是选择器来测试元素。而且
addEventListener
显然与旧版不兼容。

这应该可以在常规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);
  }
});

例如,我们有这样一个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>
这提供了与jquery非常相似的用法。

delegateClick('.btn-edit', (elm) => {

    //access the clicked DOM element
    elm;       

});

感觉像是在打代码高尔夫;)

108字节(基于@Bergi

工作演示:

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,'单击','可单击',(evt,匹配)=>{
console.log(匹配)
})

不可点击
可点击
可点击
子元素
.直肠{
宽度:100px;
高度:100px;
背景:红色;
边框:1px实心;
利润率:10px;
浮动:左;
}
.孩子{
背景:灰色;
}

可能与已查看的无用帖子重复。它有过时的链接引用,也没有我想弄明白的明确例子。我知道代表团是什么,我想知道一个如何在本国开展的例子。相反,这个问题仍然相关。评分最高的答案确实给了你一个例子。你能澄清一下你的问题吗?从这个问题上,我想你想知道关于使用普通的旧JavaScript的事件委托。对不起,我不应该说无用。它很有用。我一直在寻找将.on jquery方法(委托保护)直接翻译为本机的更多信息,如果它以“简单”的形式存在的话。@GregBurghardt:它不是重复的,因为它不要求本机实现,但这是一个很好的介绍,可以理解事件委托是关于什么的。所以假设我有一个列表(ul)和项目(li)正在动态添加的。我将使用这种方法向ul添加一个事件侦听器,生成的后续lis将运行处理程序?是,因为不是
  • 运行
    处理程序
    ,而是您附加到
      的侦听器,列表中的任何事件都会对其产生气泡。不要更改原型#smooshgate证明它永远不会有好结果。@Machado smooshgate证明您可以更改原型,如果您受欢迎,还可以更改其他人的原型世界必须永远一致。现在是2018年,MooTools仍然控制JS函数名。严肃地说:在您自己的代码中更改原型,只是要知道在
      上的
    中发生的事情是否会在以后标准化,如果
    选择器
  • 应该返回多个节点,例如是类选择器,则这不起作用。@StephenBlair您是对的。在这种情况下,您可以使用
    document.querySelectorAll(selector.forEach
    )。
    delegateClick('.btn-edit', (elm) => {
    
        //access the clicked DOM element
        elm;       
    
    });
    
    (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})