JS和JQuery中的事件委托
2017-07-04 本文已影响46人
赵碧菡
什么是事件委托(事件代理)
事件委托通俗来讲就是利用冒泡的原理,把事件追加到父级,触发执行效果。比如当一个父节点下的多个子节点绑定相同的事件时,可以利用事件冒泡机制,将事件委托给父元素执行,这时候只需要绑定一个事件便可以触发子元素的事件。
事件委托的优点
- 只需注册一个事件,节省大量内存空间。
- 可以实现 当新增子元素时不需再为其绑定事件,尤其是动态部分的内容,比如Ajax不需再为新增的元素进行绑定和对删除的元素解除绑定。
事件委托的缺点
- 事件委托是基于事件冒泡的,如果不支持事件冒泡则不能进行事件委托。
- 如果层级过多,冒泡过程中可能受阻。
事件委托使用情景
- 为DOM中的很多元素绑定相同事件;
- 为DOM中尚不存在的元素绑定事件
事件委托的实现 -------- 实例1
先看一段html代码,要实现的功能就是当点击 li 时弹出123.
<ul id="ul">
<li>111</li>
<li>222</li>
<li>333</li>
</ul>
普通方法实现,这种方法操作,每次点击li时,都会寻找目标 li 的位置,然后才能执行最后的操作。这种方法实现显然操作dom的次数很多。
var Oul=document.getElementById("ul");
var Oli=Oul.getElementsByTagName("li");
for(var i=0;i<Oli.length;i++){
Oli[i].onclick=function(){
alert(123);
}
}
下面使用事件委托来实现,用这种方法来实现 只有点击 li 时才触发事件,且每次只执行一次dom 操作。大大减少了dom操作,提高了性能。
var Oul=document.getElementById("ul");
Oul.onclick=function(e){
var e=e || window.event;
var target=e.target || e.srcElement;
if(target.nodeName.toLowerCase()=='li'){
alert(123);
alert(target.innerHTML);
}
}
事件委托的实现 -------- 实例2
当点击元素 实现的功能不一样时,怎么实现?
<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>
先看看普通方法的实现,这种方法实现至少要进行四次dom操作。
var add=docment.getElementById("add");
var remove=docment.getElementById("remove");
var move=docment.getElementById("move");
var select=document.getElementById("select");
add.onclick=function(){
alert("add");
}
remove.onclick=function(){
alert("remove");
}
move.onclick=function(){
alert(" move");
}
select.onclick=function(){
alert("select");
}
下面用事件委托来实现,只需要一次dom 操作。
var box=docment.getElementById("box");
box.onclick=function(e){
var e= e || window.event;
var target=e.target || e.srcElement;
if(target.nodeName.toLowerCase()=='input'){
switch(target.id){
case 'add':
alert("add");
break;
case 'remove':
alert("remove");
break;
case 'move':
alert("move");
break;
case 'select':
alert("select");
break;
}
}
}
事件委托的实现 -------- 实例3
为新增节点绑定事件,当鼠标移入 li 背景颜色变成红色,当鼠标 移除 li 背景颜色变为白色,点击input 添加一个 li。
<input type="button" name="" id="btn" value="添加" />
<ul id="ul">
<li>111</li>
<li>222</li>
<li>333</li>
<li>444</li>
</ul>
一样先看看普通方法的实现,使用这种方法会发现 新增的 li 没有绑定事件,而且执行dom次数非常多。为新增的 li 绑定事件,可以将for封装在一个函数里,然后再去调用这个函数。
var btn=document.getElementById("btn");
var Oul=document.getElementById("ul");
var Oli=Oul.getElementsByTagName("li");
var num=4;
for(var i=0;i<Oli.length;i++){
Oli[i].onmouseover=function(){
this.style.background='red';
}
Oli[i].onmouseout=function(){
this.style.background='#fff';
}
}
btn.onclick=function(){
++num;
var li=document.createElement('li');
li.innerHTML=num*111
Oul.appendChild(li);
}
用委托事件来实现
var btn=document.getElementById("btn");
var Oul=document.getElementById("ul");
Oul.onmouseover=function(e){
var e= e || window.event;
var target=e.target || e.srcElement;
if(target.nodeName.toLowerCase()=='li'){
target.style.background="red";
}
}
Oul.onmouseout=function(e){
var e=e || window.event;
var target=e.target || e.srcElement;
if(target.nodeName.toLowerCase()=='li'){
target.style.background="#fff";
}
}
btn.onclick=function(){
++num;
var li=document.createElement('li');
li.innerHTML=num*111
Oul.appendChild(li);
}
由上面的例子可以发现,当用事件委托的时候,根本不需要去遍历子元素直接给父元素绑定事件就可以 了。
JQuery中的事件委托
- delegate() 之后被on()方法代替。
$("ul").'li'('li','click',function(){
alert('li');
})
- on() 支持事件绑定的全部功能。
$("ul").on('click','li',function(){
alert('li');
})
delegate 和 on 的区别,selector 和events的顺序不同,on 可以省略selector ,而delegate不可以。