事件委托实践

背景:

在秋招海康威视面试时,面试官有问我这样一道题:
一个元素中有很多个元素,怎么样确定是点的哪个元素?
由于我对于事件委托的概念记不太清了,回答得不是很清楚,在这里整理一下。

事件委托

在红宝书中有如下概念:
事件流:描述的是从页面中接收事件的顺序;
事件冒泡(IE):事件开始时由最具体的元素接收,然后逐级向上传播到较为不具体的节点。
事件捕获:不太具体的节点应该更早接收到事件,而最具体的节点应该最后接收到事件。用意在于事件达到预定目标前捕获它。
事件委托:对“事件处理程序过多”问题的解决方案就是事件委托。利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。

解决问题

根据问题来设计场景,假设一个ul里面包裹五个li。我要点击不同li输出不同的结果。

<body>
    <ul id="ulEvent">
        <li id="sayHi">sayHi</li>
        <li id="sayYes">sayYes</li>
        <li id="sayNo">sayNo</li>
        <li id="sayHa">sayHa</li>
        <li id="sayEn">sayEn</li>
    </ul>
  <script>
    window.onload=function(){
        var ulEvent=document.getElementById("ulEvent");
        ulEvent.onclick = function (ev) {
                var ev = ev || window.event;
                var target = ev.target || ev.srcElement; //普通浏览器或者ie
                    switch(target.id){
                        case 'sayHi' :
                            alert('Hi');
                            break;
                        case 'sayYes' :
                            alert('Yes');
                            break;
                        case 'sayNo' :
                            alert('No');
                            break;
                        case 'sayHa' :
                            alert('Ha');
                            break;
                        case 'sayEn' :
                            alert('En');
                            break;
                    }
                }
            }
  </script>
</body>

注意:

Event对象提供了一个属性叫target,可以返回事件的目标节点,我们成为事件源,也就是说,target就可以表示为当前的事件操作的dom,但是不是真正操作dom,这个是有兼容性的,标准浏览器用ev.target,IE浏览器用event.srcElement。
所以据此我可以回答面试官:可以用target来获得目标节点。
在获得target后添加控制台输出。
当我点击yes时,控制台输出:

能得到点击时的节点。

使用事件委托的好处:

1、显而易见的是可以减少注册事件;使其集中到父事件上
2、新添加的元素同样无需绑定也可以有事件:

 <ul id="ulEve">
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
        <li>5</li>
    </ul>
    <button id="btn">添加li元素</button>

 window.onload=function(){
        var ulEvent=document.getElementById("ulEve");
        var oLi=document.getElementsByTagName('li');
        var btn=document.getElementById('btn');
        ulEvent.onclick=function(ev){
            var ev=ev||window.event;
            var target=ev.target||ev.srcElement;
            console.log(target);
            console.log(target.nodeName)  //这里输出的元素名称是全大写
            if(target.nodeName.toLowerCase()=="li"){
                alert('hi');
            }
        }
        btn.onclick=function(){
            var aLi=document.createElement('li');
            aLi.innerHTML='6'
            ulEvent.appendChild(aLi);
        }

    }


点击6的时候仍然say hi;

参考:

https://www.cnblogs.com/liugang-vip/p/5616484.html

原文地址:https://www.cnblogs.com/xmjs/p/13847040.html