zoukankan      html  css  js  c++  java
  • 事件委托

    事件委托

    事件委托指的是,不在事件的发生地(直接dom)上设置监听函数,而是在其父元素上设置监听函数,通过事件冒泡,父元素可以监听到子元素上事件的触发,通过判断事件发生元素DOM的类型,来做出不同响应。

      举例:最经典的就是ul和li标签的事件监听,比如我们在添加事件时候,采用事件委托机制,不会在li标签上直接添加,而是在ul父元素上添加。

    好处:比较合适动态元素的绑定,新添加的子元素也会有监听函数,也可以有事件触发机制。 

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

    复制代码
        <button id="btnAdd">添加</button>
        <ul id="ulList">
            <li>1</li>
            <li>2</li>
            <li>3</li>
        </ul>
        <script>
            var btnAdd = document.getElementById('btnAdd');
            var ulList = document.getElementById('ulList');
            var list = document.getElementsByTagName('li');
            var num = 3;
            btnAdd.onclick = function () {
                num++;
                var li = document.createElement('li');
                li.innerHTML = num;
                ulList.appendChild(li)
            }
            for (i = 0; i < list.length; i++) {
    list[i].onclick = function(){ alert(this.innerHTML); } } </script>
    复制代码

    结果是:新更新的HTML节点或者新添加HTML节点时,新添加的节点无法绑定事件,更新的节点也无法绑定事件,表现的行为是无法触发事件。

    其中一种解决方法是,添加子节点的时候,再次为其添加监听事件

    这也是问题所在:
     1.首先我们多次操作DOM获取元素,这样势必会降低浏览器处理性能
     2.事件不具有继承性,如果我们动态在页面中添加了一个元素,那么还需要重新走一遍上述程序为其添加监听事件

    那么有没有更好的方法呢?根据事件的冒泡原理,我们还可以实现另外一个很重要的功能:事件委托

    我们只监听最外层的元素,然后在事件函数中根据事件来源进行不同的事件处理。这样,我们添加事件监听时只需要操作一个元素,极大的降低了DOM访问,并且不用再给新增的元素添加监听事件了,因为元素的事件会冒泡到最外层,被我们截获。

    得到

    复制代码
        <button id="btnAdd">添加</button>
        <ul id="ulList">
            <li>1</li>
            <li>2</li>
            <li>3</li>
        </ul>
        <script>
            var btnAdd = document.getElementById('btnAdd');
            var ulList = document.getElementById('ulList');
            var num = 3;
    
            ulList.onclick = function(event){
                var event = event || window.event;
                var target = event.target || event.srcElement;
                if(target.nodeName.toLowerCase() == 'li'){
                    alert(target.innerHTML);
                }
            }
    
            btnAdd.onclick = function () {
                num++;
                var li = document.createElement('li');
                li.innerHTML = num;
                ulList.appendChild(li);
                doclick();
            }
        </script>
    复制代码

    这里用父级ul做事件处理,当li被点击时,由于冒泡原理,事件就会冒泡到ul上,因为ul上有点击事件,所以事件就会被触发,当然,这里当点击ul的时候也会触发的,所以要判断点击的事件是不是li标签元素。

    Event对象提供了一个属性叫target,可以返回事件的目标节点,

    这里用父级ul做事件处理,当li被点击时,由于冒泡原理,事件就会冒泡到ul上,因为ul上有点击事件,所以事件就会触发,当然,这里当点击ul的时候,也是会触发的,所以要判断点击的对象到底是不是li标签元素。

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

    这样,我们就实现了我们的事件委托,当然,不是所有的事件都是可以委托的。
    适合用事件委托的事件:click,mousedown,mouseup,keydown,keyup,keypress。

    当用事件委托的时候,根本就不需要去遍历元素的子节点,只需要给父级元素添加事件就好了,新增加的节点也可以触发事件效果。

    转自:https://www.cnblogs.com/similar/p/8502660.html

  • 相关阅读:
    docker--docker介绍
    docker--虚拟化
    高级运维工程师的打怪升级之路
    mysql常用函数
    CentOS 7 下使用 Firewall
    51nod 1094 和为k的连续区间(map+前缀和)
    51nod 1092 回文字符串(dp)
    51nod 1062 序列中最大的数(打表预处理)
    51nod 1284 2 3 5 7的倍数(容斥原理+反面思考)
    51nod 1347 旋转字符串(思维好题)
  • 原文地址:https://www.cnblogs.com/psxiao/p/11540332.html
Copyright © 2011-2022 走看看