Event

事件流

i> 事件冒泡

IE的事件流叫事件冒泡,即事件最开始有最具体的元素接收,然后逐级传播到较为不具体的节点(文档)。IE9、 Firefox、 Chrome 和 Safari 则将事件一直
冒泡到 window 对象。

1
2
3
4
5
6
7
8
9
10
<!Docuemnt>
<html>
<head>
<title>事件冒泡</title>
</head>
<body>
<div>来点死我吧</div>
</body>
</html>
如果你点击了div,那么事件将会按着 <code>&lt;div&gt;</code>--> <code>&lt;body&gt;</code> --> <code>&lt;html&gt;</code> --> <code>document</code> 这样子传播

i> 事件捕获

事件捕获的思想是不太具体的节点应该更早接收到事件,而最具体的节点应该最后接收到事件。如果仍以前面例子的话,顺序会是: document –> <html> –> <body> –> <div>
IE9、 Safari、 Chrome、 Opera和 Firefox 目前也都支持这种事件流模型。

i> DOM事件流

“DOM2级事件”规定的事件流包括三个阶段:事件捕获阶段、处于目标阶段和事件冒泡阶段。首先发生的是事件捕获,为截获事件提供了机会。然后是实际的目标接收到事件。最后一个阶段是冒泡阶段,可以在这个阶段对事件做出响应。

DOM事件流
在DOM事件流中,实际的目标(<div>元素)在捕获阶段不会接收到事件。这意味着在捕获阶段,事件从 document<html> 再到 <body> 后就停止了。
下一个阶段:“处于目标阶段”,于是事件在<div>上发生,并在事件冒泡中被看成是一部分
最后一个阶段: 冒泡阶段,事件又传回文档。

事件处理程序

i> DOM0级事件处理程序

将一个函数赋值给一个事件处理程序属性。每个元素(包括 window 和 document)都有自己的事件处理程序属性(被认为是元素的方法),这些属性通常全部小写。

1
2
3
4
var btn = document.getElementById("myBtn");
btn.onclick = function(){
alert("Clicked");
};

使用 DOM0 级方法指定的事件处理程序被认为是元素的方法。因此,这时候的事件处理程序是在元素的作用域中运行;换句话说,程序中的 this 引用当前元素

1
2
3
4
var btn = document.getElementById("myBtn");
btn.onclick = function(){
alert(this.id); //"myBtn"
};

删除DOM0级事件处理程序,

1
btn.onclick = null;

i> DOM2事件处理程序

“DOM2级事件”定义了两个方法。addEventListener(要处理的事件名, 作为事件处理程序的函数, 布尔值)removeEventListener()

  • 可以添加多个事件处理程序
  • 添加的事件处理程序也是在其依附的元素的作用域中运行。
  • 通过 addEventListener()添加的事件处理程序只能使用 removeEventListener()来移除;移除时传入的参数与添加处理程序时使用的参数相同。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//添加多个事件处理程序
var btn = document.getElementById("myBtn");
btn.addEventListener( "click", function(){
alert(this.id);
}, false);
btn.addEventListener( "click", function(){
alert("hello world");
}, false);

//删除事件处理程序
btn.removeEventListener( "click", function(){
alert(this.id);
}, false); //其实这里的匿名函数和上面的匿名函数是两个不同的函数。


//这才是用的相同的函数
var handler = function(){ alert(this.id); }

btn.addEventListener("click", handler, false);
btn.removeEventListener( "click", handler, false);

i> IE事件处理程序

attachEvent( on + “要处理的事件名” , 作为事件处理程序的函数)和 detachEvent();

  • 在IE中使用 attachEvent() 与使用 DOM0级方法 的主要区别在于 事件处理程序的作用域。在DOM0级方法下, 事件处理程序会在其所属元素的作用域内运行;在使用 attachEvent()方法 的情况下, 事件处理程序会在全局作用于中运行, 因此 this 等于 window
  • 添加多个事件处理程序不是以添加它们的顺序执行,而是以相反的顺序被触发。
  • 支持 IE 事件处理程序的浏览器有 IE 和 Opera。

i> 跨浏览器的事件处理程序。

var EventUlity = {

addHandler : function( element, eventName, handler){
   if( element.addEventListener){
       element.addEventListener( eventName, handler, false );
   }else if( element.attachEvent ){
       element.attachEvent( "on" + eventName , handler );
   }else{
       element["on" + eventName] = handler;
   }
},

removeHandler : function( element, eventName, handler){
   if( element.removeEventListener){
       element.removeEventListener( eventName, handler, false );
   }else if( element.detachEvent ){
       element.attachEvent( "on" + eventName , handler );
   }else{
       element["on" + eventName] = null;
   }
},

};

事件对象 Event

在触发 DOM 上的某个事件时 (无论使用什么方法 [ DOM0级 或 DOM2级 ]),会产生一个事件对象 event,这个对象中包含着所有与事件有关的信息。
在通过 HTML 特性指定事件处理程序时,变量 event 中保存着 event 对象。

1
<input type="button" value="Click Me" onclick="alert(event.type)"/>

Event的一些属性和方法
Event的属性和方法

在事件处理程序内部,对象this 始终等于 currentTarget, 而 target 则包含事件的实际目标。如果直接将事件处理程序指定给了目标元素,则三者相等。

1
2
3
4
5
6
7
8
9
10
  var btn = document.getElementById("myBtn");
btn.addEventListener( "click", function(event){
console.log(event.currentTarget);
console.log(this);
console.log(event.target);
}, false);

<div id="myBtn">
<a href="javascript:;">快电死我</a>
</div>

在需要通过一个函数处理多个事件时,可以使用 type 属性。例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var btn = document.getElementById("myBtn");
var handler = function(event){
switch(event.type){
case "click":
alert("Clicked");
break;
case "mouseover":
event.target.style.backgroundColor = "red";
break;
case "mouseout":
event.target.style.backgroundColor = "";
break;
}
};
btn.onclick = handler;
btn.onmouseover = handler;
btn.onmouseout = handler;

###### 这里通过检测 event.type 属性,让函数能够确定发生了什么事件,并执行相应的操作。

i> preventDefault()

只有 cancelable 属性设置为 true 的事件,才可以使用 preventDefault()来取消其默认行为。

i> stopPropagation()

用于立即停止事件在 DOM 层次中的传播,即取消进一步的事件捕获或冒泡。因此,在其父元素上注册事件就不会有任何作用。

IE中的事件对象

访问 IE 中的 event 对象:在使用 DOM0 级方法添加事件处理程序时, event 对象作为 window 对象的一个属性存在。

1
2
3
4
5
var btn = document.getElementById("myBtn");
btn.onclick = function(){
var event = window.event;
alert(event.type);
}

如果事件处理程序是使用 attachEvent()添加的,那么就会有一个 event 对象作为参数被传入事件处理程序函数中。

1
2
3
btn.attachEvent('onclick', function(event){
alert(event.type);
});

如果是通过 HTML 特性指定的事件处理程序,那么还可以通过一个名叫 event 的变量来访问 event对象(与 DOM 中的事件模型相同)。

1
<input type="button" value="Click Me" onclick="alert(event.type)">

IE 的 event 对象相关的属性和方法。

IE的event中相关属性和方法

returnValue: 与 DOM 不同的是,在此没有办法确定事件是否能被取消。
cancelBubble : 由于 IE 不支持事件捕获,因而只能取消事件冒泡;但 stopPropagatioin()可以同时取消事件捕获和冒泡。

事件类型

i>UI事件 : 指的是那些不一定与用户操作有关的事件。

  • load: 当页面完全加载后再window上触发,当所有框架都加载完毕时在框架集上出发,当图像加载完毕时在<img>上触发,或当嵌入的内容加载完毕时在<Object>上触发。
  • unload: 当页面完全卸载后在 window 上面触发,当所有框架都卸载后在框架集上面触发,或者当嵌入的内容卸载完毕后在元素上面触发。
  • abort: 在用户停止下载过程时,如果嵌入的内容没有加载完,则在元素上面触发。
  • error: 当发生 JavaScript 错误时在 window 上面触发,当无法加载图像时在元素上面触发,当无法加载嵌入内容时在元素上面触发,或者当有一或多个框架无法加载时在框架集上面触发。
  • 当用户选择文本框(<input>或<texterea>)中的一或多个字符时触发。
  • resize: 当窗口或框架的大小变化时在 window 或框架上面触发。
  • scroll:当用户滚动带滚动条的元素中的内容时,在该元素上面触发。 <body>元素中包含所加载页面的滚动条。
img元素

一般来说,在 window上面发生的任何事件都可以在<body>元素中通过相应的特性来指定,因为在 HTML 中无法访问 window 元素。实际上,这只是为了保证向后兼容的一种权宜之计,但所有浏览器都能很好地支持这种方式。

script元素

在 IE9+、 Firefox、 Opera、 Chrome 和 Safari 3+及更高版本中,