一、JavaScript事件:事件是文档或浏览器中发生的特定交互瞬间!
事件流:
1、事件冒泡:事件冒泡即事件最开始由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播至最不具体的节点(文档)。
text–>div–>body–>document–>window
2、事件捕获:事件捕获即事件最早由不太具体的节点接收,而最具体的节点最后接收到事件。
window–>document–>body–>div–>text
二、Javascript事件处理程序的3种方式
1.在DOM元素中直接绑定;
2.在JavaScript代码中绑定;
3.绑定事件监听函数。
1、HTML事件处理程序:直接在HTML代码中添加事件处理程序
<input id="btn" value="按钮" type="button" onclick="showmsg();">
<script>
function showmsg(){
alert("HTML添加事件处理");
}
</script>
2、DOM0级事件处理程序:指定对象添加事件处理
<input id="btn" value="按钮" type="button">
<script>
var btn= document.getElementById("btn");
btn.onclick=function(){
alert("DOM级添加事件处理");
}
btn.onclick=null;//如果想要删除btn的点击事件,将其置为null即可
</script>
3、DOM2级事件处理程序
DOM2也是对特定的对象添加事件处理程序,但是主要涉及到两个方法,用于处理指定和删除事件处理程序的操作:addEventListener(), attachEvent()和 removeEventListener()。它们都接收三个参数:要处理的事件名、作为事件处理程序的函数和一个布尔值(true,捕获。false,冒泡。默认false。),看下面的一段代码:
<input id="btn" value="按钮" type="button">
<script>
var btn=document.getElementById("btn");
btn.addEventListener("click",showmsg,false);//这里我们把最后一个值置为false,即不在捕获阶段处理,一般来说冒泡处
理在各浏览器中兼容性较好
function showmsg(){
alert("DOM级添加事件处理程序");
}
btn.removeEventListener("click",showmsg,false);//如果想要把这个事件删除,只需要传入同样的参数即可
</script>
DOM2级事件规定事件包括三个阶段:
1、事件捕获阶段;
2、处于目标阶段;
3、事件冒泡阶段。
补充
IE事件处理程序也对应有两个方法:attachEvent()添加事件,detachEvent()删除事件,这两个方法接收相同的两个参数:事件处理程序名称与事处理函数。这里为什么没有布尔值呢?因为ie8以及更早的版本只支持事件冒泡,所以最后一个参数默认的相当于false来处理!(支持IE事件处理程序的浏览器有IE,opera)。
三、事件委托
事件委托就是利用冒泡的原理,把事件加到父元素或祖先元素上,触发执行效果。
事件委托优点
1、提高JavaScript性能。事件委托可以显著的提高事件的处理速度,减少内存的占用。
传统写法
<ul id="list">
<li id="item1" >item1</li>
<li id="item2" >item2</li>
<li id="item3" >item3</li>
</ul>
<script>
var item1 = document.getElementById("item1");
var item2 = document.getElementById("item2");
var item3 = document.getElementById("item3");
item1.onclick = function(){
alert("hello item1");
}
item2.onclick = function(){
alert("hello item2");
}
item3.onclick = function(){
alert("hello item3");
}
</script>
事件委托
<ul id="list">
<li id="item1" >item1</li>
<li id="item2" >item2</li>
<li id="item3" >item3</li>
</ul>
<script>
var item1 = document.getElementById("item1");
var item2 = document.getElementById("item2");
var item3 = document.getElementById("item3");
document.addEventListener("click",function(event){
var target = event.target;
if(target == item1){
alert("hello item1");
}else if(target == item2){
alert("hello item2");
}else if(target == item3){
alert("hello item3");
}
})
</script>
2、动态的添加DOM元素,不需要因为元素的改动而修改事件绑定。
传统写法
<ul id="list">
<li id="item1" >item1</li>
<li id="item2" >item2</li>
<li id="item3" >item3</li>
</ul>
<script>
var list = document.getElementById("list");
var item = list.getElementsByTagName("li");
for(var i=0;i<item.length;i++){
(function(i){
item[i].onclick = function(){
alert(item[i].innerHTML);
}
})(i)
}
var node=document.createElement("li");
var textnode=document.createTextNode("item4");
node.appendChild(textnode);
list.appendChild(node);
</script>
点击item1到item3都有事件响应,但是点击item4时,没有事件响应。说明传统的事件绑定无法对动态添加的元素而动态的添加事件。
事件委托
<ul id="list">
<li id="item1" >item1</li>
<li id="item2" >item2</li>
<li id="item3" >item3</li>
</ul>
<script>
var list = document.getElementById("list");
document.addEventListener("click",function(event){
var target = event.target;
if(target.nodeName == "LI"){
alert(target.innerHTML);
}
})
var node=document.createElement("li");
var textnode=document.createTextNode("item4");
node.appendChild(textnode);
list.appendChild(node);
</script>
当点击item4时,item4有事件响应。说明事件委托可以为新添加的DOM元素动态的添加事件。