事件流:
事件冒泡:(IE的事件流),事件开始时,由最具体的元素接收,然后逐级向上传播到较为不具体的节点。
<html>
<head>
<title></title>
</head>
<body>
<div>On Click This Div</div>
</body>
</html>
点击div标签,事件传播的顺序:
<div> → <body> → <html> → document
支持大多数新旧版浏览器,放心使用。
事件捕获:(NetScape团队提出)思想是:不太具体的节点应该更早接收到事件,而最具体的节点应该最后接收到事件。
仍以前面为例,点击div标签,事件传播的顺序:
document → <html> → <body> → <div>
对旧版浏览器不支持,特殊必要条件下使用。
DOM事件流的三个阶段:
1、事件捕获阶段、2、处于目标事件阶段、3、事件冒泡阶段
事件处理程序(事件模型):
HTML事件处理程序:(在html标签里面指定事件处理程序)
<button onclick="alert('helloworld')">Click me</button>
缺点:
1、时差问题,html元素一出现在页面就触发相应的事件,但此时的事件处理程序有可能尚不具备执行条件。
2、这样扩展事件处理程序的作用域链在不同浏览器中会导致不同的结果。不同Javascript引擎遵循的标识符解析规则略有差异,很可能会在访问非限定对象成员时出错。
3、HTML与JavaScript代码紧密耦合。如果更换事件处理程序,就要改变HTML和JavaScript代码。
DOM0级事件处理程序:(所有浏览器都支持)
传统的事件处理方式:将一个函数赋值给一个事件处理程序属性:
var btn = document.getElementById("mybtn");
btn.onclick = function (){
alert('hello world.');
alert(this.id); //mybtn
};
取消事件:
btn.onclick=null;
DOM2级事件处理程序:
用于处理指定和删除事件处理程序的操作:addEventLietener(),removeEventListener()
所有的DOM节点都包含这两个方法,并且它们都接受三个参数:
1、要处理的事件名
2、作为事件处理的函数
3、一个布尔值(true表示在时间捕获阶段调用,false表示在时间冒泡阶段调用)
以上面例子为例:
btn.addEventListener("click",function(){
alert('hello world');
},false);
用DOM2级事件处理程序可以添加多个事件处理程序:
btn.addEventListener("click",function(){
alert('world hello');
},false);
这两个事件处理程序会按照添加顺序触发。
用addEventListener()添加的事件处理程序只能用removeEventListener()来移除。参数和传入
addEventListener()的参数一致(这意味着如果addEventListener()中添加的是匿名函数,则无法被移除)
所以好一点的做法:
var handle = function(){
alert(this.id);
}
btn.addEventListener("click",handle,false);
//移除
btn.removeEventListener("click",handle,false);
心得:大多数情况下将事件处理程序添加到事件流的冒泡阶段(即false),这样可以最大限度地兼容各种浏览器。
最好只在需要事件到达目标之前截获它的时候将事件处理程序添加到捕获阶段。
IE9,Firefox,Safari,Chrome,Opera支持DOM2级事件处理程序。
IE事件处理程序
attachEvent(),detachEvent(),这两个方法接收相同的两个参数:
1、事件处理程序名称(onclick...)
2、事件处理程序函数
(适用于IE8及之前版本,只支持事件冒泡)
在IE中使用attachEvent()与使用DOM0级方法的主要区别在于作用域:
1、DOM0级:事件处理程序会在其所属元素的作用域内运行
2、attachEvent():事件处理程序会在全局作用域内运行
因此:
btn.attachEvent("onclick",function(){
alert(this === window);// true;
});
在编写跨浏览器代码时要特别注意着一点。
与addEventListener()不同的地方还有:
可以为一个元素添加多个事件处理程序,但是它们会按照添加顺序的相反顺序来执行。
支持IE事件处理的只有IE和Opera
跨浏览器的事件处理程序:
1 var EventUtil = {
2 addHandler:function(element,type,handler){
3 if(element.addEventListener){
4 element.addEventListener(type,handler,false); //DOM2
5 }else if(element.attachEvent){
6 element.attachEvent("on"+type,handler); //IE
7 }else{
8 element["on"+type] = handler; //DOM0
9 }
10 },
11 removeHandler:function(element,type,handler){
12 if(element.removeEventListener){
13 element.removeEventListener(type,handler,false); //DOM2
14 }else if(element.detachEvent){
16 element.detachEvent("on"+type,handler); //IE
17 }else{
18 element["on"+type] = null; //DOM0
19 }
20 }
21 };
事件对象:
1、DOM(DOM0,DOM2)事件对象主要的属性:
event.type:事件的类型(click...)
event.target:事件的目标(HTMLInput...)
event.currentTarget:被绑定事件的那个元素。注意currentTarget和target的区别。target是当前事件的实际对象(作用点),而currentTarget则是真正绑定事件的那个元素。
event.stopPropagation():阻止事件冒泡
event.preventDefault():阻止事件的默认事件
2、IE事件对象的主要属性:
type:事件的类型(click...)
event.srcElement:事件的目标
eg:兼容性的写法:
alert(tar);
}
event.cancelBubble = true|false :true,阻止事件冒泡,false不阻止冒泡。
event.returnValue = true | false :false:阻止事件的默认行为