事件委托——前端面试

事件委托又名事件代理。

定义:事件委托就是利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。

为了便于理解,我们还是用取快递的例子:

HW公司有三个员工有快递,那么有两个方式取快递。

(1)三个人都等在公司门口,等快递小哥过来取快递;

(2)委托前台帮忙代取快递,并核对信息;

即,对于(2)对于公司已有员工的快递,前台也能核对信息签收,对于公司新入职的员工,也能进行记录并核对。

为什么要用事件委托呢?

在javascript中访问dom节点的次数越多,引起浏览器重绘与重排的次数就会越多,就会延长整个页面交互事件。如果使用事件委托,将所有与dom有关的操作放在js中,与dom的交互只有一次,就能提高性能。

对很多元素进行操作时,如果一个一个执行渲染,那真的是对性能的巨大浪费,但是转换思维,如果对他的父元素进行操作,那么只需进行一次,既节省内存,又提高了性能。

事件委托如何实现?

引用学习中的例子进行讲解:

    <ul id="ul_list">
        <li>111</li>
        <li>222</li>
        <li>333</li>
        <li>444</li>
    </ul>

功能:点击li元素,实现弹框“触发li弹窗事件”

常规写法:

    var ulList = document.getElementById("ul_list");
    var liList = ulList.getElementsByTagName("li");
    for (var i = 0; i < liList.length; i++) {
        liList[i].onclick = function () {
            alert("触发li弹窗事件")
        }
    }

对于常规写法,首先要找到父级元素ul,在循环给子元素添加事件,如果是100个li元素,那性能自然是不高。

事件委托:


    var ulList = document.getElementById("ul_list");
    ulList.onclick = function () {
        alert("触发li弹窗事件")
    }

对于事件委托写法,点击li元素时,li元素会触发事件冒泡到达父元素,则触发对应事件;同时点击ul也是一样。

功能:只点击li才会发生效果

event事件提供了target属性,target永远表示当前事件的dom,即当前的事件,不是冒泡到的事件。

    var ulList = document.getElementById("ul_list");
    ulList.onclick = function (e) {
        // console.log(e)
        var e = e || window.event;
        var target = e.target || e.srcElement;
        if (target.nodeName === 'LI') {
            alert("触发li弹窗事件" + target.innerHTML)

        }
    }

每个操作都不相同

    <ul id="ul_list">
        <li id="li1">111</li>
        <li id="li2">222</li>
        <li id="li3">333</li>
        <li id="li4">444</li>
    </ul>
    var li1 = document.getElementById("li1")
    var li2 = document.getElementById("li2")
    var li3 = document.getElementById("li3")
    var li4 = document.getElementById("li4")
    li1.onclick = function(){
        console.log("this is li1!")
    }
    li2.onclick = function(){
        console.log("this is li2!")
    }
    li3.onclick = function(){
        console.log("this is li3!")
    }
    li4.onclick = function(){
        console.log("this is li4!")
    }

每个操作都不相同的事件委托

    var ulList = document.getElementById("ul_list");
    ulList.onclick = function (e) {
        var e = e || window.event;
        var target = e.target || e.srcElement;
        if (e.target.nodeName === "LI") {
            switch (target.id) {
                case 'li1':
                    console.log("this is li1!")
                    break;
                case 'li2':
                    console.log("this is li2!")
                    break;
                case 'li3':
                    console.log("this is li3!")
                    break;
                case 'li4':
                    console.log("this is li4!")
                    break;
            }
        }
    }

只进行一次dom操作即可实现对应效果。

对于新增节点:


    var btn = document.getElementById("btn");
    var ulList = document.getElementById("ul_list");
    var liList = ulList.getElementsByTagName('li');
    var num = liList.length;

    //鼠标悬浮改变颜色,移除变回白色
    for (var i = 0; i < liList.length; i++) {
        liList[i].onmouseover = function () {
            this.style.background = 'lightBlue';
        };
        liList[i].onmouseout = function () {
            this.style.background = '#fff';
        };
    }
    //添加新节点
    btn.onclick = function () {
        num++;
        var newLi = document.createElement('li');
        newLi.innerHTML = 111 * num;
        ulList.appendChild(newLi);
    };

新增节点没有效果节点对应的事件效果。

那么改变方式仍然是用事件委托,在父节点上添加事件。

    var btn = document.getElementById("btn");
    var ulList = document.getElementById("ul_list");
    var liList = ulList.getElementsByTagName('li');
    var num = liList.length;

    //鼠标悬浮改变颜色,移除变回白色
    ulList.onmouseover = function (e) {
        var e = e || e.srcElement;
        var target = e.target || e.srcElement;
        if (target.nodeName === "LI") {
            target.style.background = 'lightBlue';
        }
    };
    ulList.onmouseout = function (e) {
        var e = e || e.srcElement;
        var target = e.target || e.srcElement;
        if (target.nodeName === "LI") {
            target.style.background = '#fff';
        }
    };

    //添加新节点
    btn.onclick = function () {
        num++;
        var newLi = document.createElement('li');
        newLi.innerHTML = 111 * num;
        ulList.appendChild(newLi);
    };

本文是学习与分享。欢迎指正。

  参考链接:js中的事件委托或是事件代理详解 - 凌云之翼 - 博客园

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值