一. 事件
事件的三个阶段:事件捕获 -> 事件目标 -> 事件冒泡
捕获阶段:先由文档的根节点document往事件触发对象,从外向内捕获事件对象;
目标阶段:到达目标事件位置(事发地),触发事件;
冒泡阶段:再从目标事件位置往文档的根节点方向回溯,从内向外冒泡事件对象
事件捕获:事件发生时首先发生在document上,然后依次传递给body,最后到达目的节点(即事件目标),事件流模型:div →body→ html→ document 。
图示说明:
onclick 事件冒泡,重写onlick会覆盖之前属性,没有兼容性问题
addEventListener(event.type, handle, boolean); IE8及以下不支持,属于DOM2级的方法,可添加多个方法不被覆盖。事件类型没有on,第三个参数false,表示在事件第三阶段(冒泡)触发,true表示在事件第一阶段(捕获)触发。如果绑定同一个事件同一个方法,只会执行一次,所以如果handle是同一个方法,只执行一次。
attachEvent(event.type, handle ); IE特有,兼容IE8及以下,可添加多个事件处理程序,只支持冒泡阶段,可以多次进行绑定,所以如果handle是同一个方法,绑定几次执行几次,同时事件类型要加on。
默认事件行为:href=""链接,submit表单提交等
阻止默认事件:
return false; 阻止独享属性(通过on这种方式)绑定的事件的默认事件,阻止浏览器对事件的默认处理,只在当前函数有效,不会影响其他外部函数的执行
event.preventDefault( ); 阻止通过 addEventListener( ) 添加的事件的默认事件
event.returnValue = false; 阻止通过 attachEvent( ) 添加的事件的默认事件
事件的绑定与事件的解绑
事件的绑定:
代码如下:
function addEvent(element,eType,handle,bol){
// 支持addEventListener
if(element.addEventListener){
element.addEventListener(eType,handle,bol);
// 支持attachEvent
}else if(element.attachEvent){
element.attachEvent("on"+eType,handle);
// 兼容的onclick的绑定
}else{
element["on"+eType] = handle;
}
}
事件的解绑:
代码如下:
function removeEvent(element,eType,handle,bol){
// 支持addEventListener
if(element.addEventListener){
element.addEventListener(eType,handle,bol);
// 支持attachEvent
}else if(element.attachEvent){
element.detachEvent("on"+eType,handle);
// 兼容的onclick的绑定
}else{
element["on"+eType] = null;
}
}
封装函数:通过事件冒泡的方式,兼容事件捕获只需要添加个bool参数
代码如下:
var EventUtil = {
addEvent: function(element,type,handle){
if(element.addEventListener){
element.addEventListener(type,handle,false);
}else if(element.addEvent){
element.addEvent("on"+type,handle);
}else{
element["on"+type] = handle;
}
},
removeEvent:function(element,type,handle){
if(element.removeEventListener){
element.removeEventListener(type,handle,false);
}else if(element.removeEvent){
element.removeEvent("on"+type,handle);
}else{
element["on"+type] = null;
}
}
}
二、事件冒泡
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>事件冒泡</title>
</head>
<body>
<div id="div1">div1
<div id="div2">div2</div>
</div>
</body>
<script>
var div1 = document.getElementById("div1");
var div2 = document.getElementById("div2");
div1.onclick = function(){
console.log("我是div1");
};
div2.onclick = function(){
console.log("我是div2");
};
</script>
</html>
说明:两个父子关系的div1和div2,分别给div1和div2绑定了点击事件。当点击div1的时候,控制台打印输出 我是div1。当点击div2的时候,控制台打印输出 我是div2 和 我是div1,在这个时候就说明了当我们子点击div2的时候,div1的事件也被触发了,父级事件被触发,这种现象相当于就是冒泡事件。
function stopBubble(env){
// 如果提供事件对象,说明为非IE浏览器
if(env && env.stopPropagation){
env.stopPropagation();
}else{
// IE浏览器
window.event.cancelBubble = true;
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>事件冒泡2</title>
<style>
.d1 {
width: 300px;
height: 300px;
background-color: skyblue;
display: none;
}
</style>
</head>
<body>
<button id="btn">按钮</button>
<div class="d1"></div>
</body>
<script>
// 单击动作会从btn传到document中,发生事件冒泡
var btn = document.getElementById("btn");
var d1 = document.getElementsByClassName("d1")[0];
// 点击按钮的时候,元素d1显示
btn.onclick = function(e){
d1.style.display = "block";
// 阻止冒泡
stopBubble(e);
};
// 点击网页其它地方的时候,元素d1隐藏
document.onclick = function(){
d1.style.display = "none";
};
// 阻止浏览器的默认行为函数,事件冒泡
// event.stopPropagation 阻止事件冒泡的方法
function stopBubble(e) {
// 非IE浏览器阻止冒泡
if( e && e.stopPropagation )
e.stopPropagation();
else
// IE浏览器阻止冒泡
window.event.cancelBubble = true;
}
</script>
</html>
说明:定义一个按钮,在按钮下面有一个div的元素d1,默认为隐藏。点击按钮的时候,元素d1显示。在点击按钮的时候,调用了阻止事件冒泡的发生函数stopBubble()。点击docume网页其它地方的时候,元素d1隐藏。
三、跨浏览器的事件对象
var EventUtil={
getEvent:function(event){
return event||window.event;
},
getTarget:function(event){
return event.target||event.srcElement;
},
preventDefault:function(){
if(event.preventDefault){
event.preventDefault();
}else{
event.returnValue=false;
}
},
stopPropagation:function(){
if(event.stopPropagation){
event.stopPropagation();
}else{
event.cancelBubble=true;
}
},
addEvent:function(element,type,handler){
if(element.addEventListener){
element.addEventListener(type,handler,false);
}else if(element.attachEvent){
element["e"+type]=function(){
handler.call(element)
}
element.attachEvent("on"+type,element["e"+type]);
}else{
element["on"+type]=handler;
}
},
removeEvent:function(element,type,handler){
if(element.removeEventListener){
element.removeEventListener(type,handler,false);
}else if(element.detachEvent){
element.detachEvent("on"+type,element["e"+type]);
element["e"+type]=null;
}else{
element["on"+type]=null;
}
}
};