事件是将JavaScript与网页联系在一起的主要方式。
事件流
事件流:从页面中接收到事件的顺序。
事件冒泡
IE的事件流叫做事件冒泡:事件开始时由最具体 的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播到较为不具体 的节点(文档)。
事件捕获
Netscape Communicator团队提出的,与事件冒泡相反。
用意:在事件到达预定目标之前捕获它。
DOM 事件流
“DOM2 级事件”规定的事件流包括三个阶段:事件捕获阶段、处于目标阶段、事件冒泡阶段。
事件处理程序
事件:用户或浏览器自身执行的某种动作。如:click
、load
、mouseover
等。事件处理程序:响应某个事件的函数。
HTML事件处理程序
<script type="text/javascript">
function showMessage(){
alert("Hello World!");
}
</script>
<input type="button" value ="Click Me" onclick="showMessage()" />
DOM0 级事件处理程序
- 添加
var btn = document.getElementById("myBtn");
btn.onclick = function (){
alert(this.id);
}
- 删除事件处理程序
btn.onclick = null;
DOM2 级事件处理程序
addEventListener(要处理的事件名, 作为事件处理程序的函数,布尔值)
removeEventListener(要处理的事件名, 作为事件处理程序的函数,布尔值)
布尔值:
-
true
:在捕获阶段调用事件处理程序 -
false
:在冒泡阶段调用事件处理程序
var btn = document.getElementById("myBtn");
var hander = function(){
alert(this.id);
};
// 添加事件处理程序
btn.addEventListener("click", hander, false);
// 删除事件处理程序
btn.removeEventListener("click", hander, false);
主要好处:可以添加多个事件处理程序,按照添加的顺序触发。
IE事件处理程序
attachEvent(事件处理程序名称, 事件处理程序函数)
detachEvent(事件处理程序名称, 事件处理程序函数)
var btn = document.getElementById("myBtn");
var hander = function(){
alert(this.id);
};
// 添加事件处理程序
btn.attachEventr("onclick", hander);
// 删除事件处理程序
btn.detachEvent("onclick", hander);
主要好处:可以添加多个事件处理程序,按照添加相反的顺序触发。
跨浏览器的事件处理程序
addHander(要操作的元素, 事件名称, 事件处理程序函数)
removeHander(要操作的元素, 事件名称, 事件处理程序函数)
事件对象
event
事件对象
阻止事件捕获、事件冒泡:
var btn = document.getElementById("myBtn");
btn.onclick = function(event){
alert("Clicked");
event.stopPropagation();
};
document.body.onclick = function(event){
alert("Body clicked");
};
事件类型
-
UI事件:不一定与用户操作有关的事件
- DOMActive 不建议使用
- load
- unload
- abort
- error
- resize
- scroll
-
焦点事件
- blur 失去焦点时 不会冒泡
- DOMFocusIn 获得焦点 冒泡
- DOMFocusOut 失去焦点
- focus 获得焦点 不会冒泡
- focusin
- focusout
- 鼠标与滚轮事件
-
键盘与文本事件
- keydown
- keypress
- keyup
- 复合事件
- 变动事件
- HTML5 事件
- 设备事件
- 触摸与手势事件
事件性能
- 事件处理程序是函数。
- 在JavaScript中,每个函数都是对象,都会占用内存。
- 内存中的对象越多,性能就越差。
事件委托
目的:解决“事件处理程序过多”问题。
实现:利用了事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。
使用事件委托,只需要在 DOM 树中尽量最高的层次上添加一个事件处理程序。
如下例子,由于所有列表项都是这个元素"myLinks"的子节点,而且它们的事件会冒泡,所以单击事件最终会被这个函数处理。
<!DOCTYPE html>
<html>
<head>
<title>Event Delegation Example</title>
<script type="text/javascript" src="EventUtil.js"></script>
</head>
<body>
<ul id="myLinks">
<li id="goSomewhere">Go somewhere</li>
<li id="doSomething">Do something</li>
<li id="sayHi">Say hi</li>
</ul>
<script type="text/javascript">
(function(){
var list = document.getElementById("myLinks");
EventUtil.addHandler(list, "click", function(event){
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
switch(target.id){
case "doSomething":
document.title = "I changed the document's title";
break;
case "goSomewhere":
location.href = "http://www.wrox.com";
break;
case "sayHi":
alert("hi");
break;
}
});
})();
</script>
</body>
</html>
移除事件处理程序
- 从文档中移除带有事件处理程序的元素时,最好先手工移除事件处理程序。以免内存中留有“空事件处理程序”。
btn.onclick = null;
- 在卸载页面之前,先通过
onunload
事件处理程序移除所有事件处理程序。以免内存中留有“空事件处理程序”。
模拟事件
在测试Web应用程序中,模拟触发事件是一种极其有用的技术。
流程:
- 创建事件对象
- 初始化事件对象
- 触发事件
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。