博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
事件委托
阅读量:4359 次
发布时间:2019-06-07

本文共 4997 字,大约阅读时间需要 16 分钟。

  • 111
  • 222
  • 333
  • 444

实现功能是点击li,弹出123:

window.onload = function(){    var oUl = document.getElementById("ul1");    var aLi = oUl.getElementsByTagName('li');    for(var i=0;i

 上面的代码的意思很简单,相信很多人都是这么实现的,我们看看有多少次的dom操作,首先要找到ul,然后遍历li,然后点击li的时候,又要找一次目标的li的位置,才能执行最后的操作,每次点击都要找一次li;

那么我们用事件委托的方式做又会怎么样呢?

window.onload = function(){    var oUl = document.getElementById("ul1");   oUl.onclick = function(){        alert(123);    }}

 

这里用父级ul做事件处理,当li被点击时,由于冒泡原理,事件就会冒泡到ul上,因为ul上有点击事件,所以事件就会触发,当然,这里当点击ul的时候,也是会触发的,那么问题就来了,如果我想让事件代理的效果跟直接给节点的事件效果一样怎么办,比如说只有点击li才会触发,不怕,我们有绝招:

Event对象提供了一个属性叫target,可以返回事件的目标节点,我们成为事件源,也就是说,target就可以表示为当前的事件操作的dom,但是不是真正操作dom,当然,这个是有兼容性的,标准浏览器用ev.target,IE浏览器用event.srcElement,此时只是获取了当前节点的位置,并不知道是什么节点名称,这里我们用nodeName来获取具体是什么标签名,这个返回的是一个大写的,我们需要转成小写再做比较(习惯问题):

window.onload = function(){

  var oUl = document.getElementById("ul1");
  oUl.onclick = function(ev){
    var ev = ev || window.event;
    var target = ev.target || ev.srcElement;
    if(target.nodeName.toLowerCase() == 'li'){
         alert(123);
         alert(target.innerHTML);
    }
  }
}

 

这样改下就只有点击li会触发事件了,且每次只执行一次dom操作,如果li数量很多的话,将大大减少dom的操作,优化的性能可想而知!

 

上面的例子是说li操作的是同样的效果,要是每个li被点击的效果都不一样,那么用事件委托还有用吗?

window.onload = function(){            var Add = document.getElementById("add");            var Remove = document.getElementById("remove");            var Move = document.getElementById("move");            var Select = document.getElementById("select");                        Add.onclick = function(){                alert('添加');            };            Remove.onclick = function(){                alert('删除');            };            Move.onclick = function(){                alert('移动');            };            Select.onclick = function(){                alert('选择');            }                    }

 

上面实现的效果我就不多说了,很简单,4个按钮,点击每一个做不同的操作,那么至少需要4次dom操作,如果用事件委托,能进行优化吗?

window.onload = function(){            var oBox = document.getElementById("box");            oBox.onclick = function (ev) {                var ev = ev || window.event;                var target = ev.target || ev.srcElement;                if(target.nodeName.toLocaleLowerCase() == 'input'){                    switch(target.id){                        case 'add' :                            alert('添加');                            break;                        case 'remove' :                            alert('删除');                            break;                        case 'move' :                            alert('移动');                            break;                        case 'select' :                            alert('选择');                            break;                    }                }            }                    }

 

用事件委托就可以只用一次dom操作就能完成所有的效果,比上面的性能肯定是要好一些的 

 

 现在讲的都是document加载完成的现有dom节点下的操作,那么如果是新增的节点,新增的节点会有事件吗?也就是说,一个新员工来了,他能收到快递吗?

看一下正常的添加节点的方法:

    
  • 111
  • 222
  • 333
  • 444

 

现在是移入li,li变红,移出li,li变白,这么一个效果,然后点击按钮,可以向ul中添加一个li子节点

 

window.onload = function(){            var oBtn = document.getElementById("btn");            var oUl = document.getElementById("ul1");            var aLi = oUl.getElementsByTagName('li');            var num = 4;                        //鼠标移入变红,移出变白            for(var i=0; i

 

这是一般的做法,但是你会发现,新增的li是没有事件的,说明添加子节点的时候,事件没有一起添加进去,这不是我们想要的结果,那怎么做呢?一般的解决方案会是这样,将for循环用一个函数包起来,命名为mHover,如下:

window.onload = function(){            var oBtn = document.getElementById("btn");            var oUl = document.getElementById("ul1");            var aLi = oUl.getElementsByTagName('li');            var num = 4;                        function mHover () {                //鼠标移入变红,移出变白                for(var i=0; i

 

虽然功能实现了,看着还挺好,但实际上无疑是又增加了一个dom操作,在优化性能方面是不可取的,那么有事件委托的方式,能做到优化吗?

window.onload = function(){            var oBtn = document.getElementById("btn");            var oUl = document.getElementById("ul1");            var aLi = oUl.getElementsByTagName('li');            var num = 4;                        //事件委托,添加的子元素也有事件            oUl.onmouseover = function(ev){                var ev = ev || window.event;                var target = ev.target || ev.srcElement;                if(target.nodeName.toLowerCase() == 'li'){                    target.style.background = "red";                }                            };            oUl.onmouseout = function(ev){                var ev = ev || window.event;                var target = ev.target || ev.srcElement;                if(target.nodeName.toLowerCase() == 'li'){                    target.style.background = "#fff";                }                            };                        //添加新节点            oBtn.onclick = function(){                num++;                var oLi = document.createElement('li');                oLi.innerHTML = 111*num;                oUl.appendChild(oLi);            };        }

转载于:https://www.cnblogs.com/ytg1120/p/6247632.html

你可能感兴趣的文章
Java之String
查看>>
20155212 2017-2018-1 《信息安全系统设计》第7周学习总结
查看>>
新手C#ListView使用记录2018.08.03
查看>>
1028: 可乐(2018年中南大学研究生复试机试题 )
查看>>
珍藏的最全的windows操作系统快捷键
查看>>
【DBAplus】SQL优化:一篇文章说清楚Oracle Hint的正确使用姿势
查看>>
二叉树结点删除操作
查看>>
图论-单源最短路-SPFA算法
查看>>
转换文件的字符集
查看>>
prometheus + grafana安装部署(centos6.8)
查看>>
Redis和Memcached的区别【转】
查看>>
VMware: Deploy multiple VM’s from template with PowerCLI
查看>>
Cascaded pose regression
查看>>
model,map,MapAndVivew用于页面跳转时候使用的即跳转后才添加属性 这样再回调中无法使用 因为回调的前提是页面不调转;解决的方法是用responsewrite(普通的字符响应)...
查看>>
自动在数据库中创建表
查看>>
如何在一个进程中启动另外一个线程:ProcessStartInfo Constructor
查看>>
树状数组模板题 P1904
查看>>
Kerberos安装及使用
查看>>
android 布局中 layout_gravity、gravity、orientation、layout_weight
查看>>
highcharts
查看>>