事件代理原理

      一、定义:事件代理(事件委托):指当有大量子元素触发事件时,将事件监听器绑定在父元素进行监听,(真正绑定事件的是外层元素,⽽不是⽬标元素)此时数百个事件监听器变为了一个监听器,提升了网页性能。

     二、本质:通过冒泡原理来实现的:

        1.事件分为三个阶段: 先捕获,后目标,再冒泡;只能有一个阶段触发程序执行

        2.事件经过的所有元素都没有被处理,这个事件就会消失

        3.事件的传递过程是与结构上的嵌套关系有关,而非视觉上的嵌套关系
(从上往下)事件捕获:嵌套关系的元素,会存在事件捕获的功能,同一事件自父元素捕获至子元(从下往上)事件冒泡:嵌套关系的元素,会存在事件冒泡的功能,同一事件自父元素冒泡至子元素

      三、举个例子:

       现想通过点击按钮添加新列表4,5,6,但是由于是事件已经是绑定完后才新添加上去的,没有得到事件绑定,我们点击新添加的列表时就不会出现像点击列表123时打印的效果,这时候我们就要用到事件代理。将原本应该绑定在子元素当的点击事件绑定到父元素身上。

     <ul>
        <li class="myli">列表1</li>
        <li class="myli">列表2</li>
        <li class="myli">列表3</li>
    </ul>
    <button>添加li</button>

 <script>
        let myli = document.querySelectorAll(".myli");
        let but = document.querySelector("button");
        let ul = document.querySelector("ul");
        let num = 3;

        but.onclick = function () {
            let li = document.createElement("li");
            num++;
            li.innerHTML = "列表" + num;
            li.className = "myli";
            ul.appendChild(li);
        }

        for (let i = 0; i < myli.length; i++) {
         myli[i].onclick = function(){
             console.log(myli[i].innerHTML);
            }

        }

 </script>

       此时我们点击新增列表4 5 是不会出现打印效果的,这是因为我们只将点击事件绑定到了原本有的子元素身上,新增的子元素没有得到事件绑定。所以我们要通过事件代理来实现让新的子元素也能有打印的效果,其本质是通过冒泡原理来实现的:将子元素上的事件冒泡到父元素身上让其一样能被实现。

 <body>
    <ul>
        <li class="myli">列表1</li>
        <li class="myli">列表2</li>
        <li class="myli">列表3</li>
    </ul>
    <button>添加li</button>
    <script>
        let myli = document.querySelectorAll(".myli");
        let but = document.querySelector("button");
        let ul = document.querySelector("ul");
        let num = 3;

        but.onclick = function () {
            let li = document.createElement("li");
            num++;
            li.innerHTML = "列表" + num;
            li.className = "myli";
            ul.appendChild(li);
        }

        // for (let i = 0; i < myli.length; i++) {
        //    myli[i].onclick = function(){
        //     console.log(myli[i].innerHTML);
        //    }

        // }



        //target:事件对象里面的属性 点击事件发生后存的元素节点
        ul.onclick = function (e) {
            // console.log(111);
            //实现当前被点击的元素(列表)时打印
            if (e.target.className == "myli") {
                console.log(e.target.innerHTML);
            }
        }
    </script>
</body>

     四、总结:

      优点:

        1.提高性能,节约内存

        2.新添加的子元素也可以绑定上事件

     局限性:

      1.有些事件(没有冒泡特性的)不可以用事件代理进行绑定,比如focus、blur

    主要解决的问题:

    解决静态的事件绑定问题;解决业务相同,而性能消耗却更高的问题。

    适合用事件代理的事件:

   click、mousedown、mouseup、keydown、keyup、keypress
 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值