举个栗子详解事件代理

作者: mytac | 来源:发表于2017-11-07 15:45 被阅读31次

原文链接

为啥要使用事件代理

我们在开发中,可能会遇见这样的需求:

在一个列表中点击每个列表项,将每个列表项中的内容传入某个函数中进行处理。

通常结构为

    <ul id="list">
        <li>msg</li>
        <li>msg1</li>
        <li>msg2</li>
        <li>msg3</li>
    </ul>

这里需要点击某个列表项,弹出他的内容文本,不难写出下面的方法:

window.onload = () => {
            const ulNode = document.getElementById("list")
            const liNodes = ulNode.childNode || ulNode.children
            for (let i = 0; i < liNodes.length; i++) {
                liNodes[i].addEventListener('click', (e) => {
                        alert(e.target.innerHTML)
                    }, {
                        once: true
                    }) // once:在调用一次后被移除
            }
        }
效果如图

然而,当我们对这个大列表进行dom操作时,比如添加一个节点,但上面的事件并没有绑定到这个新节点上,需要我们再次调用这个函数,重新遍历这些子节点,绑定事件。


如图

了解事件捕获和冒泡

事件捕获:当某个元素触发某个事件(如onclick),顶层对象document就会发出一个事件流,随着DOM树的节点向目标元素节点流去,直到到达事件真正发生的目标元素。在这个过程中,事件相应的监听函数是不会被触发的。

事件目标:当到达目标元素之后,执行目标元素该事件相应的处理函数。如果没有绑定监听函数,那就不执行。

事件冒泡:从目标元素开始,往顶层元素传播。途中如果有节点绑定了相应的事件处理函数,这些函数都会被一次触发。如果想阻止事件起泡,可以使用e.stopPropagation()(Firefox)或者e.cancelBubble=true(IE)来组织事件的冒泡传播。

img

使用事件代理

当子节点被点击时,click事件向上冒泡,父节点捕获到事件后,我们判断是否为所需的节点,然后进行处理。代码如下:

       const ulNode = document.getElementById("list")
       ulNode.addEventListener('click',(e)=>{
            // e.target为当前元素的子节点,这里只对li元素进行处理
            if(e.target&&e.target.nodeName.toLowerCase()==='li'){
                alert(e.target.innerHTML)
            }
       })

        const btn = document.getElementById('btn')
        btn.onclick = () => {
            const newLi=document.createElement('li')
            const text=document.createTextNode("new msg")
            newLi.appendChild(text)
            ulNode.appendChild(newLi)
        }
效果如图

不需要再次为新节点绑定事件,照样会响应。

当我们把新建的子节点改成p元素时,

 const newLi=document.createElement('p')
如图

因为做了判断,所以点击p元素是没有响应的。

相关文章

  • 举个栗子详解事件代理

    原文链接 为啥要使用事件代理 我们在开发中,可能会遇见这样的需求: 在一个列表中点击每个列表项,将每个列表项中的内...

  • 事件代理

    javascript和jQuery的事件代理不同写法 首先思考一下:为什么我们要用到事件代理??? 举个栗子父元素...

  • JS写事件代理

    js中的事件委托或是事件代理详解

  • 9.21

    JQ的事件和动画 1.事件 先举个栗子: $(function(){ $("div").bind("clic...

  • Vue2.0 探索之路——生命周期和钩子函数的一些理解

    beforecreate : 举个栗子:可以在这加个loading事件created :在这结束loading,还...

  • 举个栗子

    【问题】苹果商店用户反馈不能注册、不能修改密码、不能使用企业支付 【假设】员工反馈的这些问题是因为信息不对称。员工...

  • 举个“栗子”

    举个栗子 举把剑 举只皮卡丘 举只大白 举个艾斯 举个钢铁侠 举只福娃

  • 举个栗子

    秋季没有做过多的停留便要匆匆要离去,冬季也按耐不住它激动的心情早早探出头来。措手不及的你是否还在冷风中发抖?这种氛...

  • 举个栗子

    最近一个之前的同事因为找工作的事向我寻求帮助,但说实话,能力有限,我也帮不了多少。 只是在和同事说到面试中关于思维...

  • 举个栗子。

    好的广告,不仅仅能打动人,还能让人立刻产生行动。 “啤酒饮料矿泉水,花生瓜子八宝粥。” 每次听到这亲切的呼唤, 我...

网友评论

    本文标题:举个栗子详解事件代理

    本文链接:https://www.haomeiwen.com/subject/mcsjmxtx.html