由于dom标准和浏览器是在并行"进化"的,在Dom3标准定案的时候(2004年),浏览器已经开发了多个版本了。IE4是在1995年完成的,Mozilla也已经开发了。造成的结果是对dom标准的事件支持在不同浏览器是有差异的。
标准的Dom把事件模型分成捕获性事件和冒泡型事件。
捕获型事件:事件传递从最外层的元素传递到最内层的元素,最外层的元素先响应。
冒泡型事件:最内层的元素先响应,事件传递然后冒泡到最外层的元素。
示例图如下:
在IE9以前只支持冒泡模型:(从IE9开始支持W3C标准,同时支持捕获和冒泡)
我们来看一些具体的例子:
1,下面的例子中通过对元素的onclick属性赋值,事件发生的模型是在捕获阶段,在IE中的结果是alert("span clicked");,alert("divclicked");在firefox中是alert("span clicked");,alert("div clicked");alert("window clicked");【IE中没有window响应click事件】
<html>
<head>
<title>test</title>
<meta http-equiv=content-type content="text/html; charset=gb2312">
<script type="text/javascript">
window.οnlοad=function(){
var div1 = document.getElementById("div");
var span = document.getElementById("sid");
window.onclick = function(){
alert("window clicked");
}
span.onclick = function(){
alert("span clicked");
}
div1.onclick = function(){
alert("div clicked");
}
};
</script>
</head>
<body>
<div id='div'>
<span id='sid'>textspan</span>
</div>
</body>
</html>
2,在FireFox中支持捕获型和冒泡型事件,下面的代码执行的结果如下
alert('Dom: div addEventListener true');//捕获的先发生
alert("span clicked");,
alert("div clicked");
alert('Dom div addEventListener false');
alert("window clicked");
在IE中执行为:
alert("span clicked");,
alert("div clicked");
alert('IE: div attachEvent'); if(window.event){ //IE Browser
div.attachEvent("onclick",function(){
alert('IE: div attachEvent');
});
}else{
div.addEventListener("click",function(){
alert('Dom: div addEventListener true');
},true); //capture phase
div.addEventListener("click",function(){
alert('Dom div addEventListener false');
},false); //bubble phase
}
同时,在为元素添加事件的方法也是不同的,在IE中是attachEvent,在DOM标准中是addEventListener,同时可以指定时间模型,true为捕获,false为冒泡。
如何阻止事件在冒泡阶段被一个内层元素响应后,不再向外冒泡,示例如下:
window.οnlοad=function(){
var div1 = document.getElementById("div");
var span = document.getElementById("sid");
window.onclick = function(){
alert("window clicked");
}
span.onclick = function(){
alert("span clicked " + getSrcElement(getEvent(arguments[0])));
if(window.event){
window.event.cancelBubble=true;
}else{
arguments[0].stopPropagation();//Dom标准中会将第一个参数作为event
}
}
div1.onclick = function(){
alert("div clicked" + getSrcElement(getEvent(arguments[0])));
}
if(window.event){
div.attachEvent("onclick",function(){
alert('IE: div attachEvent');
//alert(window.event);
});
}else{
div.addEventListener("click",function(){
alert('Dom: div addEventListener true');
//alert(window.event);
},true);
div.addEventListener("click",function(){
alert('Dom div addEventListener false');
//alert(window.event);
},false);
}
function getEvent(eve){
return window.event || eve;
}
function getSrcElement(oEvent){
return oEvent.srcElement || oEvent.target;
}
};
在上面的例子中,IE中只会alert("div clicked" + getSrcElement(getEvent(arguments[0])));
在FireFox中: Dom: div addEventListener true 【捕获阶段发生的】和span clicked [object HTMLSpanElement]
在IE中是通过设置window.event.cancelBubble=true;在Dom标准中是event.stopPropagation();,同时IE中获取事件源是srcElement,在Dom标准中是target。