事件流
事件流描述的是从页面中接受事件的顺序。
IE团队提出的事件流概念为事件冒泡流--------事件开始是由最具体的元素(文档中嵌套层次最深的节点)接收。然后再逐级向上传播到较为不具体的节点(文档)。
以下面HTML为例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="myDiv">Click me</div>
</body>
</html>
冒泡事件流顺序:div---body---html---document
div---body---document (IE5.5-)
div---body---html---document---window(IE9、Firefox、Chrome、Safari)
Netscape Communicator团队提出的事件流概念为事件捕获流———事件开始是由不具体的节点(文档)接收。然后再逐级向下传播到最具体的元素(文档中嵌套层次最深的节点)。
冒泡事件流顺序:window---document---html---body---div
提示:老版本浏览器不支持事件捕获,因此建议放心使用事件冒泡,特殊情况再使用事件捕获。
DOM事件流
DOM2级事件规定事件流三个阶段:事件捕获、处于目标阶段、事件冒泡。
事件捕获阶段:捕获事件
处于目标阶段:实际目标接收到事件
事件冒泡阶段:对事件作出响应
虽然多数浏览器都规范明确要求捕获阶段不涉及事件目标,但IE9、Chrome、Safari、Firefox、Opera9.5+都会在事件捕获阶段处罚事件对象上的事件。
事件处理程序
HTML事件处理程序:
//写在HTML代码中的事件处理程序代码
<input type="button" value="Click Me" onclick="alert('clicked')"/>
//不能使用未经转义的HTML语法字符,(eg:&、""、<、>)只能使用转义之后
<input type="button" value="Click Me" onclick="alert("clicked")"/>
//也可以调用页面其他地方定义的脚本
<input type="button" value="Click Me" onclick="showMessage()"/>
<script type="text/javascript">
function showMessage() {
alert(11);
}
</script>
//自动生成一个局部变量(事件对象)event,可以直接访问事件对象
<input type="button" value="Click Me" onclick="alert(event.type)"/>
//存在this,this就是执行代码的目标元素即input
<input type="button" value="Click Me" onclick="alert(this.value)"/>
//这样创建的函数作用域有一个扩展,即可以访问本身作用域及document;如果是表单元素还会访问form中量。
缺点:存在时差问题,(showMessage函数若还没有加载出来时点击按钮会出错);
扩展的作用域链在不同浏览器中解析结果不同;
若更换事件处理程序,需两处都更改,工作量大。
DOM0级事件处理程序
//事件冒泡流阶段处理
<div type="button" value="Click Me" id="myBtn"></div>
<script type="text/javascript">
var btn=document.getElementById("myBtn");
btn.onclick=function () {
alert(this.id);//元素的方法,this指的是当前元素
};
btn.onclick=null;//删除事件处理程序
</script>
缺点:存在时差问题,(脚本文件若还没有加载出来时点击按钮会没有反应);
只能添加一个事件处理程序,若是多个,后面的会覆盖前面的。
DOM2级事件处理程序
//addEventListener();removeEventListener();
<script type="text/javascript">
var btn=document.getElementById("myBtn");
//匿名函数无法移除
btn.addEventListener("click",function () {
alert(this.id);//元素的方法,this指的是当前元素
},false);
btn.addEventListener("click",showMessage,false);
btn.removeEventListener("click",showMessage,false);//删除事件处理程序
</script>
ture:捕获阶段调用事件处理程序
false:冒泡阶段调用事件处理程序
大多数情况下是false,可以最大限度的兼容各种浏览器;特殊情况下再使用true。
优点:可以添加多个事件处理程序且不会被覆盖。
IE事件处理程序
IE8-支持冒泡事件。(IE、Opera)
//attachEvent();detachEvent();
<script type="text/javascript">
var btn=document.getElementById("myBtn");
//匿名函数无法移除
btn.attachEvent("click",function () {
alert(this===window);//true,在全局作用域中执行
});
btn.attachEvent("click",showMessage);
btn.detachEvent("click",showMessage);//删除事件处理程序
</script>
可以添加多个事件处理程序且不会被覆盖。
跨浏览器的事件处理程序
<script>
var EventUtil= {//对象
addHandler: function(element, type, handler) {
if (element.addEventListener) {//DOM2
element.addEventListener(type, handler, false);
}
else if (element.attachEvent) {//IE8
element.attachEvent("on" + type, handler);
}
else {//DOM0
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;
}
}
};
var handler = function(){
alert("123");
};
EventUtil.addHandler(btn, "click", handler);
EventUtil.removeHandler(btn, "click", handler);
</script>
缺点:没有考虑IE作用域问题
但是对于添加事件移除事件足够了