JS 中事件绑定、事件监听和事件委托的区别
1、事件绑定:
为了让 JavaScript 对用户做出的操作进行响应,需要给DOM元素绑定事件处理函数,常见的事件处理函数有
onclick、onchange、onkeyup、onkeydown、onmousemove、onmouseover等
事件绑定有三种方式:
-
直接在DOM中绑定事件
<button id="btn2" onclick="clickBtn()">不要点我哟~</button> <script> function clickBtn(){ alert('都说不要点我啦'); } </script>
-
在JavaScript中绑定事件
<button id="btn">点我~</button> <script> document.getElementById("btn").onclick = function(){ alert("快点我!!!"); } </script>
-
使用事件监听绑定事件 两种方式:addEventListener() 和 attachEvent()
<button id="btn">点我~</button> <script> btn.addEventListener("click",function(){ alert("我是被监听的btn~"); },false); btn.attachEvent("onclick",function(){ alert("我是被监听的btn2~"); }) </script>
2、事件监听
事件监听与事件绑定的区别:
事件绑定只能为一个元素的相同事件绑定一个响应函数,后面绑定的响应函数会覆盖之前绑定的响应函数
事件监听可以为一个元素的相同事件同时绑定多个响应函数,当事件被触发时,响应函数将会按照函数的绑定顺序执行
事件监听有两种方式:addEventListener() 和 attachEvent()
addEventListener() 和 attachEvent() 区别:
(1) 兼容性
attachEvent:兼容:IE7、IE8;不兼容firefox、chrome、IE9、IE10、IE11、safari、opera
addEventListener 兼容:firefox、chrome、IE、safari、opera;不兼容IE7、IE8及以下
(2) 执行顺序
addEventListener( ) :当事件被触发时,响应函数将会按照函数的绑定顺序执行
attachEvent( ): 当事件被触发时,响应函数将会按照与函数绑定顺序相反的顺序执行(与addEventListener相反)
事件监听的优点:
1、可以绑定多个事件
2、可以解除相应绑定
解除绑定
addEventListener( ) 事件:
<button id="btn">点我~</button>
<script>
function tag(){
alert("tag2");
}
btn.addEventListener("click",function(){
alert("tag1");
},false);
btn.addEventListener("click",tag2,false);
btn.addEventListener("click",function(){
alert("tag3");
},false);
btn.removeEventListener("click",tag2,false);
</script>
执行结果:
tag1
tag3
attachEvent( )事件:
<button id="btn">点我~</button>
<script>
function tag(){
alert("tag2");
}
btn.attachEvent("onclick",function(){
alert("tag1");
})
btn.attachEvent("onclick",tag)
btn.attachEvent("onclick",function(){
alert("tag3");
})
btn.detachEvent("onclick",tag);
</script>
执行结果:
tag3
tag1
addEventListener( ) 事件
参数:
1、事件的字符串,不要on
2、回调函数,当事件触发时该函数会被调用
3、(可选)是否在捕获阶段触发事件,需要一个布尔值,true(捕获),false(冒泡),一般都传false(冒泡)
<button id="btn">点我~</button>
<script>
btn.addEventListener("click",function(){
alert("tag1");
},false);
btn.addEventListener("click",function(){
alert("tag2");
},false);
btn.addEventListener("click",function(){
alert("tag3");
},false);
</script>
执行顺序:
tag1
tag2
tag3
attachEvent( )事件
在IE8中可以使用attachEvent()绑定事件
参数:
1、事件的字符串,要on
2、回调函数
//attachEvent( ) 事件
<button id="btn">点我~</button>
<script>
btn.attachEvent("onclick",function(){
alert("tag1");
})
btn.attachEvent("onclick",function(){
alert("tag2");
})
btn.attachEvent("onclick",function(){
alert("tag3");
})
</script>
执行顺序:
tag3
tag2
tag1
封装事件监听
//addEventListener()中的this,是绑定事件的对象
//attachEvent()中的this,是window
function bind(obj,eventStr,callback){
if(obj.addEventListener){
obj.addEventListener(eventStr,callback,false);
}else{
obj.attachEvent("on"+eventStr,function(){
callback.call(obj);//this是谁由调用方式决定,在匿名函数中调用回调函数
});
}
}
3、事件传播、事件冒泡、事件委托
事件传播(三个阶段):
1.捕获阶段
在捕获阶段从最外层的祖先元素,向目标元素进行事件的捕获,但是默认此时不会触发事件
2.目标阶段
事件捕获到目标元素,捕获结束开始在目标元素上触发事件
3.冒泡阶段
事件从目标元素向它的祖先元素传递,依次触发祖先元素上的事件
注意:IE8及以下没有捕获阶段
事件冒泡:
所谓的冒泡指的是事件上的向上传导,当后代元素上的事件被触发时,其祖先元素的相同事件也会被触发,在开发中大部分冒泡都是有用的,如果不希望发生事件冒泡可以通过事件对象来取消冒泡
取消冒泡(两种方法)
IE浏览器:event.cancelBubble = true; 不符合W3C标准,只支持IE浏览器,但是在新版本chrome,opera浏览器中已经支持
其他浏览器:event.stopPropagation() 属于W3C标准,不支持IE
//封装
function stopPropagation(event){
event = event || window.event;
if(document.all){
event.cancelBubble = true;
}else{
event.stopPropagation();
}
}
事件委托:
指将事件统一绑定给元素的共同的祖先元素,这样当后代元素上的事件触发时,会一直冒泡到祖先元素从而通过祖先元素的响应函数来处理事件
优点:
1、提高JavaScript性能。事件委托可以显著的提高事件的处理速度,减少内存的占用
2、动态的添加DOM元素,不需要因为元素的改动而修改事件绑定。
<button id="btn">新建超链接</button>
<ul id="box1">
<li><a class="link" href="javascript:;">超链接一</a></li>
<li><a class="link" href="javascript:;">超链接二</a></li>
<li><a class="link" href="javascript:;">超链接三</a></li>
</ul>
<script>
var btn = document.getElementById("btn");
var ul = document.getElementById("box1");
btn.onclick = function(){
var li = document.createElement("li");
li.innerHTML = "<a class=\"link\" href=\"javascript:;\">新建的超链接</a>";
ul.appendChild(li);
}
ul.onclick = function(event){
event = event || window.event;
/*
因为当我们点击其他不是a标签的元素时,也会触发ul的响应函数
target
event 事件中target表示的是触发事件的对象
如果触发时间的对象是我们期望的元素,则执行,否则不执行
*/
if(event.target.className == "link")
window.alert("我是ul的单击响应函数~");
}
</script>