事件冒泡、捕获和事件委托

事件冒泡与捕获

  1. 事件冒泡:事件从触发事件的节点开始一直向上传播直至父节点。
  2. 事件捕获:事件从父级节点开始一直传递到触发事件的节点。

当你使用事件捕获时,父级元素先触发,子级元素后触发,即div先触发,p后触发。
当你使用事件冒泡时,子级元素先触发,父级元素后触发,即p先触发,div后触发。
IE只支持事件冒泡,Mozilla, Opera 7 和 两种都支持。
如何决定使用捕获还是冒泡呢?
(1)一般是利用addEventListener()来绑定事件。
element.addEventListenner(“eventname”,function,boolean)
方法的第三个参数是bool型,如果是TRUE那么表式采用事件捕获;若是FALSE,表明是事件冒泡,默认是false。即:
true = 捕获
false = 冒泡

(2)IE浏览器下采用attachEvent()方法,
element.attachEvent(“eventname”,function)

阻止事件冒泡的方法:
W3C中:event.stopPropagation()
IE下设置:cancelBubble=true

DOM事件流有三个阶段:事件捕获、处于目标阶段、事件冒泡。
在这里插入图片描述

事件委托

只指定一个事件处理程序,将原本子元素上的处理程序委托给父元素执行。如果目标元素上的其他事件处理程序使用了stopPropagation()阻止了事件传播,那么事件委托就会失效。

事例:如 ul下有多个li元素时,可以将’li’元素的事件处理程序委托给ul元素,这样即使后期添加li也无需再去添加事件处理程序了。
click、mousedown、mouseup、keydown、keyup 和 keypress事件可以用事件委托。
下面是事件委托处理的例子。

<ul id="parent">
        <li>item 1</li>
        <li>item 2</li>
        <li>item 3</li>
        <li>item 4</li>
        <li>item 5</li>
        <li>item 6</li>
    </ul>
     <script>
        window.onload = function(){
            var parent = document.getElementById('parent'); //获取ul元素
             parent.addEventListener('click',function(event){
                var event = event || window.event;  //兼容写法
                var target = event.target || event.srcElement;  //兼容属性写法
                if(target.nodeName.toLowerCase() == 'li'){
                    alert(target.innerHTML);
                }
            },false)
        }
    </script>

target属性
定义:event对象有个target属性,标准浏览器下是target,IE浏览器是srcElement属性。target事件属性可返回事件的目标节点即触发该事件的节点。
语法:
event.target
event.target.nodeName // 获取事件触发元素标签(如 li、p标签等)
event.target.[ id /className /innerHTML ]

jQuery中的事件委托方法
自1.7版本后,on()方法代替了bind()、delegate()、live()。
—$ (selector).bind(“click”,function):bind会直接把处理程序绑定到各个元素上,它不能把处理程序绑定到还未存在于页面中的元素之上。若是新的链接经由AJAX加入到了页面中,那么bind处理程序对于这些新加入的链接来说是无效的。
bind缺点:
①它会绑定事件到所有的选出来的元素上,当绑定的元素较多时(如:表格的每个单元格),会查找和遍历每个单元格,导致脚本执行速度明显变慢;且保存表格的多个单元格元素和相应的处理程序也会占用大量内存。简言之:绑定元素较多时,效率低下,占用内存
②. bind只能给调用它的时候已经存在的元素绑定事件,不能给未来新增的元素绑定事件,即不能动态绑定到新增的元素上
③. 当页面加载完的时候,才可以进行bind()

----$ (selector).live(“click”,function)
live缺点:
①. $ ()函数会找到当前页面中的所有td元素并创建jQuery对象,但在确认事件目标时却不用这个td元素集合,而是使用选择符表达式与event.target或其祖先元素进行比较,因而生成这个jQuery对象会造成不必要的开销
②. 默认把事件绑定到$ (document)元素,如果DOM嵌套结构很深,事件冒泡通过大量祖先元素会导致性能损失,即存在事件传播链过长的问题
③. 只能放在直接选择的元素后面,不能在连缀的DOM遍历方法后面使用,即$ (“table td”).live…可以,但$(“table”).find(“td”).live…不行

----$ (selector).delegate(“li”,“click”,function)
----$ (selector).on(“click”,“li”,“function”)

 $(function(){
             $("#parent").on("click","li",function(event){
                 var target = $(event.target);
                target.css("background-color","red");
             })
         })

参考资料:
https://www.cnblogs.com/EnSnail/p/5838630.html

猜你喜欢

转载自blog.csdn.net/Qian_mos/article/details/84799055