事件相关概念
- 事件是与浏览器或文档交互的瞬间,如点击按钮,填写表格等,它是JS与HTML之间交互的桥梁。
- 事件类型是一个用来说明发生什么类型事件的字符串。例如mousemove”表示用户鼠标移动。
- 事件目标是发生的事件或与之相关的对象。当讲事件时,我们必须同时指明类型和目标。例如,window上的load事件或者
- 事件处理程序或事件监听程序时处理或响应事件的函数。应用程序通过指明事件类型和事件目标,在WeLb浏览器中注册它们的事件处理程序函数。
- 事件对象是与特定事件相关且包含有关该事件的详细信息的对象。事件对象作为参数传递给事件处理程序函数(不包括IE8之前的版本,在这些浏览器中有时仅能通过全局变量event才能得到)。所有事件的对象都有用来指定事件类型的type和指定事件目标的target属性(在IE8之前版本中用srcElement而非target属性)。
- 事件传播是浏览器决定哪个对象触发其事件处理程序的过程。事件传播有两种形式,一种是事件冒泡,另一种是事件捕获。
事件类型
- DOM事件
- HTML5事件
- 触摸屏和移动设备事件
事件处理程序
- DOM0级模型
又称为原始事件模型,在该模型中,事件不会传播,即没有事件流的概念。
- 设置javascript对象属性为事件处理程序
1 | var btn = document.getElementById('.btn'); |
缺点:每个事件目标对于每种事件类型将最多只有一种处理程序。
- 设置HTML标签属性为事件处理程序
这种方式设置事件处理程序,html标签的属性值应该是javascript代码字符串,不应该是用大括号包围且使用function关键字的前缀;如果包含多条javascript语句,必须使用分号隔开或者断开属性值使其跨多行。
1 | <input type="button" onclick="alert('hello word!')"> |
缺点:这种方式将 HTML 代码与 JavaScript 代码耦合在一起,不利于代码的维护,所以应该尽量避免使用这样的方式。
- DOM2级模型
属于W3C标准模型,现代浏览器(除IE6-8之外的浏览器)都支持该模型。在该事件模型中,一次事件共有三个过程:
1 | <!DOCTYPE html> |
事件捕获阶段(capturing phase)。事件从document一直向下传播到目标元素, 依次检查经过的节点是否绑定了事件监听函数,如果有则执行。
document->html->body->div
事件处理阶段(target phase)。事件到达目标元素, 触发目标元素的监听函数。
事件冒泡阶段(bubbling phase)。事件从目标元素冒泡到document, 依次检查经过的节点是否绑定了事件监听函数,如果有则执行。
div->body->html->document
addEventListener()
addEventListener()接受三个参数,第一个是注册处理程序的类型;第二个是指定类型的事件发生时应该调用的函数;第三个是布尔值,通常情况下会给这个参数传递false,如果相反传递了true,那么函数将注册为捕获事件处理程序,并在事件不同的调用阶段调用。
1 | var btn = document.getElementById('.btn'), |
var eventUtils={
// 添加句柄
addHandler:function(element,type,handler){
if(element.addEventListener){
element.addEventListener(type,handler,false);
}else if(element.attachEvent){
element.attachEvent(‘on’+type,handler);
}else{
element[‘on’+type]=handler;
}
},
// 删除句柄
removeHandler:function(element,type,handler){
if(element.removeEventListener){
element.removeEventListener(type,handler,false);
}else if(element.detachEvent){
element.detachEvent(‘on’+type,handler);
}else{
element[‘on’+type]=null;
}
},
//获取事件对象
//IE模型中event是一个全局唯一的对象绑定在window对象上
getEvent:function(event){
return event?event:window.event;
},
//获取类型
getType:function(event){
return event.type;
},
getElement:function(event){
return event.target || event.srcElement;
},
//阻止默认事件
preventDefault:function(event){
if(event.preventDefault){
event.preventDefault();
}else{
event.returnValue=false;
}
},
//阻止冒泡
stopPropagation:function(event){
if(event.stopPropagation){
event.stopPropagation();
}else{
event.cancelBubble=true;
}
}
}
```
小结
事件是将 JavaScript 与网页联系在一起的主要方式。DOM3 级事件规范和 HTML5 定义了常见的大多数事件。即使有规范定义了基本事件,但很多浏览器仍然在规范之外实现了自己的专有事件,从而为开发人员提供更多掌握用户交互的手段。有些专有事件与特定设备关联,例如移动 Safari 中的 orientationchange 事件就是特定关联 iOS 设备的。
在使用事件时,需要考虑如下一些内存与性能方面的问题。
- 有必要限制一个页面中事件处理程序的数量,数量太多会导致占用大量内存,而且也会让用户感觉页面反应不够灵敏。
- 建立在事件冒泡机制之上的事件委托技术,可以有效地减少事件处理程序的数量。
- 建议在浏览器卸载页面之前移除页面中的所有事件处理程序。