DOM事件级别
DOM事件模型
DOM事件模型分为两类:
- 一类是IE所使用的冒泡型事件(Bubbling);
- 另一类是DOM标准定义的冒泡型与捕获型(Capture)的事件。
除IE外的其他浏览器都支持标准的DOM事件处理模型。
DOM事件处理程序
事件就是用户或浏览器自身执行的某种动作。
诸如click、load、mouseover ,都是事件的名字。
而响应某个事件的函数就叫做事件处理程序
(或事件侦听器)
HTML事件处理程序
<input type="button" value="click me" onclick="alert('clicked')">
由于 onclick 里包含的是 JavaScript代码, 因此不能再其中使用未经转义的HTML语法字符,比如 &、“”、’‘、< 、>
<input type="button" value="click me" onclick="alert("clicked"')">
在HTML中定义的事件处理程序可以调用脚本里定义的方法
<script>
function showMessage() {
alert('hello');
}
</script>
<input type="button" value="click me" onclick="showMessage()">
HTML事件处理程序的一个缺点:HTML与JavaScript代码紧密耦合。如果要更换事件处理程序,就需要改动两个地方。所以转而使用JavaScript指定事件处理程序
DOM0级事件处理程序
<button id = 'myBtn'>click me</button>
<script>
var btn = document.getElementById('myBtn');
btn.onclick = function(event){
alert(event.target);
}
</script>
btn.onclick 这种方式添加的事件处理程序会在事件流的冒泡阶段被处理
解除DOM0级事件
btn.onclick = null;
将事件处理程序设置为mull之后,再单击按钮将不会有任何动作发生
一个dom对象只能注册一个同类型的函数,因为注册多个同类型的函数的话,就会发生覆盖,之前注册的函数就会无效。
var btn = document.getElementById('myBtn');
btn.onclick = function(){
console.log(this.id);
alert('you click the first function');
};
btn.onclick = function(e){
var e = e || window.event;
alert('you click the second function');
console.log(this === e.currentTarget); // true
console.log(this === btn); // true
}
上述代码只执行第二个注册的函数
DOM0级事件处理程序优点
- 简单
- 跨浏览器【所有现代浏览器支持】
- this 指向被绑定的DOM元素,即 event.currentTarget
DOM0级事件处理程序缺点
- 一次只能绑定一个事件处理器在DOM元素上
- function参数中的event参数只对非IE浏览器有效果(因为IE浏览器有特制的window.event)。
DOM2级事件处理程序
“DOM2级事件”定义了两个方法来处理和删除事件,所有DOM节点中都包含这两种方法
- 注册事件:
element.addEventListener('eventName', function(e){}, true) // 捕获方式
- 删除事件:
element.removeEventListener('eventName', function(e){}, false) // 冒泡方式
最后一个参数是布尔型,true代表捕获事件,false代表冒泡事件。
DOM2级方法可以添加多个事件处理程序
var btn = document.getElementById('myBtn');
btn.addEventListener('click',function(){
alert('click one');
},false);
btn.addEventListener('click',function(){
alert('click two');
},false);
以上事件处理程序按照添加他们的方法顺序触发,先弹“click one”,再弹“click two”
解除DOM2级事件
通过 addEventListener() 添加的事件处理程序只能使用 removeListener() 来移除;
移除时传入的参数与添加程序时使用的参数相同;
所以通过 addEventListener() 添加的匿名函数无法移除
var btn = document.getElementById('myBtn');
var handler = function(){
alert('click one');
}
btn.addEventListener('click',handler,false);
btn.removeEventListener('click',handler,false); // 有效
DOM2级事件处理程序优点
- DOM2支持同一dom元素注册多个同种事件。
- DOM2新增了捕获和冒泡的概念。
note:
IE9、firefox、Safari、chrome、Opera 都支持DOM2级事件处理程序; IE8及更早版本不支持DOM事件流(事件捕获); 为了最大限度地兼容各种浏览器,建议将事件处理程序添加到事件流的冒泡阶段。
IE事件处理程序
- 注册事件:
element.attachEvent('onclick', function(){})
- 移除事件:
element.detachEvent('onclick', function(){})
IE8及更早版本只支持事件冒泡,通过attachEvent() 添加的事件处理程序会被添加到冒泡阶段
IE事件中的this
在IE中使用attachEvent() 与使用DOM0级方法的主要区别在于事件处理的作用域。
- 在DOM0级方法,事件处理程序会在其所属元素的作用域内运行;
- 使用attachEvent(),事件处理程序在全局作用域中运行,
this === window
var btn = document.getElementById('myBtn');
btn.attachEvent('onclick', function(){
console.log(this === window); // true
})
IE事件为一个元素添加多个事件处理程序
var btn = document.getElementById('myBtn');
btn.attachEvent('onclick', function(){
console.log('clicked');
});
btn.attachEvent('onclick', function(){
console.log('hello');
});
attachEvent()为按钮添加了两个不同的事件处理程序,与DOM方法不同,而是以相反的顺序被触发
。
先弹出“Hello”,再弹出”clicked”
IE事件移除 同DOM方法一样,传入相同函数的引用
var btn = document.getElementById('myBtn');
var handler = function(){
alert('click one');
}
btn.attachEvent('onclick', handler);
btn.detachEvent('onclick', handler); // 有效
跨浏览器的事件处理程序EventUtil
var EventUtil = {
addHandler: function(element, type, fn) {
if (element.addEventListener) {
element.addEventListener(type, fn, false);
} else if (element.attachEvent) {
element.attachEvent("on" + type, fn);
} else {
element['on' + type] = fn;
}
},
removeHandle: function(element, type, fn) {
if (element.removeEventListener) {
element.removeEventListener(type, fn, false);
} else if (element.detachEvent) {
element.detachEvent("on" + type, fn);
} else {
element['on' + type] = fn;
}
}
}
使用EventUtil对象
var btn = document.getElementById('myBtn');
var handler = function() {
console.log('test');
}
EventUtil.addHandler(btn, "click", handler);
EventUtil.removeHandler(btn, "click", handler);
DOM1、DOM3级事件
- DOM1中没有规定事件相关的内容
- DOM3级事件模块在DOM2级事件模块的基础上重新定义了某些事件,也添加了一些新事件。
customeEvent自定义事件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>test</title>
</head>
<body>
<div id="myDiv">click me, 事件捕获完整阶段</div>
<script>
var myDiv = document.getElementById("myDiv");
var eve = new Event('test');
myDiv.addEventListener('test', function() {
console.log('test dispatch');
}, false);
myDiv.dispatchEvent(eve);
</script>
</body>
</html>