事件冒泡、事件捕获、默认事件与事件代理(委托)

来源:互联网 发布:手游数据互通什么意思 编辑:程序博客网 时间:2024/06/07 15:58

之前偶然间遇到需要一个事件冒泡的问题,虽然有看过相关的分析,但要用到还是记不清楚,就在这里整理一下这4个事件吧。

<div class="parent" onclick="alert("par")">    <div class="child" onclick="alert("chi")">    </div></div>

事件冒泡:

点击child,先触发child事件,再冒泡到parent,触发父级事件(会一直冒泡到文档根);
这个过程是可以阻止的,方法obj.stopPropagation():(多益二笔考了这个,结果我给忘了……)

事件捕获:

点击child,先触发parent事件,再逐级往下进行捕获到child,触发child事件;

默认事件:

浏览器具有默认行为,诸如a标签的点击跳转,右键点击跳出菜单等;
阻止默认事件:obj.preventDefault();(多益二笔和阻止默认事件一起考的,这个我记得);

事件冒泡和事件捕获的选择

(IE默认事件冒泡,其他浏览器默认捕获)
其中addEventListener()中 true为捕获,false为冒泡;

obj.addEventListener("click",function(){},true)  //捕获obj.addEventListener("click",function(){},false)  //冒泡

事件代理(委托)

以下参考了js中的事件委托或是事件代理详解,并做了精简和提炼

首先,事件代理是利用了事件冒泡的!(之前一直好奇事件冒泡这种不方便的东西有什么用…..直到了解了事件代理)
比如现在的需求是有100个li标签,每个都要给他设置个点击事件;最直接的方法是写个for循环,遍历添加事件。

但是在JavaScript中,添加的事件处理程序数量将关系到页面的整体运行性能,因为需要不断的与dom节点进行交互,访问dom的次数越多,引起浏览器重绘与重排的次数也就越多,就会延长整个页面的交互就绪时间,这就是为什么性能优化的主要思想之一就是减少DOM操作的原因;如果要用事件委托,就会将所有的操作放到js程序里面,与dom的操作就只需要交互一次,这样就能大大的减少与dom的交互次数,提高性能;

给每个li添加事件:

<ul id="ul">    <li>111</li>    <li>222</li>    <li>333</li>    <li>444</li></ul>
var oUl = document.getElementById("ul");oUl.onclick = function(){    alert(123);}

当li被点击时,由于冒泡原理,事件就会冒泡到ul上,因为ul上有点击事件,所以事件就会触发。
但是,这里当点击ul的时候,也是会触发的,那么如果我想让事件代理的效果跟直接给节点的事件效果一样怎么办?比如说只有点击li才会触发。

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

var oUl = document.getElementById("ul");oUl.onclick = function(e){ //兼容IE var e = e || window.event; var target = e.target || e.srcElement; if(target.nodeName == 'LI'){    alert(123);    alert(target.innerHTML);  }}

给每个子节点添加不同事件

之前做了个购物车的DEMO
在一个tr中,几个td的点击事件不同,这是就要用到switch

简单的例子:
<div id="box">        <input type="button" id="add" value="添加" />        <input type="button" id="remove" value="删除" />        <input type="button" id="move" value="移动" />        <input type="button" id="select" value="选择" /></div>
var oBox = document.getElementById("box");oBox.onclick = function (e) {    var e = e || window.event;    var target = e.target || e.srcElement;    if(target.nodeName == 'INPUT'){        switch(target.id){            case 'add' :                alert('添加');                break;            case 'remove' :                alert('删除');                break;            case 'move' :                alert('移动');                break;            case 'select' :                alert('选择');                break;        }    }}

增加子节点时

当父级不使用代理事件,给其添加子节点时,子节点的点击事件也要添加!这就又增加了一个dom操作。
当父级代理事件时,该子节点不用添加点击事件就会因为事件冒泡触发父级的代理事件!

原创粉丝点击