# DOM 事件
# 事件
事件
:就是用户或浏览器自身执行的某种动作。如:click、load 和 mouseover。
# 事件处理程序
事件处理程序(事件侦听器)
:是响应某个事件的函数。如:onclick、onload。
# 事件流
事件流
:描述的是从页面中接收事件的顺序。
# 事件冒泡
事件冒泡
:IE 的事件流叫做事件冒泡。事件开始时由最具体的元素接收,然后逐级向上传播到较为不具体的节点(文档)。
# 事件捕获
事件捕获
:Netscape 提出的另一种事件流叫事件捕获。由不太具体的节点先接收到事件,最具体的节点最后接收到事件。
# DOM 事件流
DOM事件流
:“DOM2 级事件”规定的事件流包含三个阶段。事件捕获阶段、处于目标阶段和事件冒泡阶段。
多数浏览器都实现了“DOM2 级事件”规范的事件流。但 IE9、Safari、Chrome、Firefox 和 Opera 9.5 及更高版本都会在捕获阶段触发事件对象上的事件。结果,就是有两个机会在目标对象上面操作事件。
# 指定事件处理程序
为事件指定处理程序的方式有:
HTML事件处理程序
DOM0级事件处理程序
DOM2级事件处理程序
IE事件处理程序
跨浏览器的事件处理程序
# HTML 事件处理程序
HTML事件处理程序
:是在 HTML 标签内为与事件处理程序同名的特性(属性)指定的处理程序。这个处理程序可以是在行内直接执行的 JavaScript 代码,也可以调用在页面其他地方定义的脚本(代码)。
<!-- 行内代码 -->
<input type="button" value="Click Me" onclick="alert('Clicked')" />
<!-- 调用函数 -->
<script type="text/javascript">
function showMessage() {
alert('Hello World!');
}
</script>
<input type="button" value="Click Me" onclick="showMessage()" />
<!-- 删除事件处理程序可以通过指定相应的事件属性为null -->
# DOM0 级事件处理程序
DOM0级事件处理程序
是指,先取得一个要操作的对象的引用,将一个函数赋值给他的事件处理程序属性。以这种方式添加的事件处理程序会在事件流的冒泡阶段被处理。DOM0 级方法指定的事件处理程序被认为是元素的方法。因此,这时候的事件处理程序是在元素的作用域中运行;换句话说,程序中的 this 引用当前元素。例子:
// 要使用js指定事件处理程序,首先必须取得一个要操作的对象的引用
var btn = document.getElementById('myBtn');
btn.onclick = function() {
alert(this.id); // "myBnt"
};
btn.onclick = null; // 删除事件处理程序
# DOM2 级事件处理程序
DOM2级事件处理程序
:“DOM2 级事件”定义了两个方法,用于处理指定和删除事件处理程序的操作:addEvenvtListener()
和 removeEventListener()
。所有 DOM 节点中都包含这 2 个方法,并且它们都接收 3 个参数:要处理的事件名、作为事件处理程序的函数和一个布尔值。最后这个布尔值参数如果是 true
,表示在捕获阶段调用事件处理程序;如果是 false
,表示在冒泡阶段调用事件处理程序。
var btn = document.getElementById("myBtn");
btn.addEventListener("click",function(){
// 与DOM0级方法一样,这里添加的事件处理程序也是在其依附的元素的
// 作用域中运行
alert(this.id);
}, false);
// DOM2级方法添加事件处理程序的主要好处是可以添加多个事件处理程序。
// 会按添加的顺序被触发
btn.addEventListener("click",function(){
alert("Hello World!");
}, false);
// 通过addEventListene()添加的事件处理程序只能用
// removeEventListener()来移除.所以添加的匿名函数将无法移除。
btn.removeEventListener("click",function(){ // 没有用!
alert(this.id);
}, false);
var handler = function(){
alert(this.id);
};
btn.addEventListener("click",handler,false);
btn.removeEventListener("click",handler,false); // 有效!
大多数情况下,都是将事件处理程序添加到冒泡阶段,这样可以最大限度地兼容各种浏览器。不是特别需要不建议在事件捕获阶段注册事件处理程序。
# IE 事件处理程序
IE事件处理程序
,IE 实现了与 DOM 类似的两个方法:attachEvent()和 detachEvent()。这两个方法接收相同两个参数:事件处理程序名称和事件处理程序函数。由于 IE8 及更早版本只支持事件冒泡,所以通过 attachEvent()添加的事件只会被添加到冒泡阶段。
var btn = document.getElememtById('myBtn');
// 注意第一个参数是“onclick”,而 DOM 的 addEventListener()是“click”
btn.attachEvent('onclick', function() {
alert('Clicked');
});
// attachEvent()与 DOM0 级方法的主要区别在于,事件处理程序的作用域。
// DOM0 级方法,事件处理程序会在其所属元素的作用域内运行;
// 用 attachEvent(),事件处理程序会在全局作用域中运行,this 等于 window
btn.attachEvent('onclick', function() {
alert(this === window); // true
});
// 与 addEventListener()类似,attachEvent()可以添加多个事件处理程序
// 区别是,执行顺序是与添加顺序相反的,最后添加的先执行。
// 上面代码会先显示 true,然后显示 Click
// 与 addEventListener()一样,添加的匿名函数无法移除
btn.detachEvent('onclick', function() {
// 无效!
alert('Click');
});
var handler = function() {
alert('Click');
};
btn.attachEvent('onclick', handler);
btn.detachEvent('onclick', handler); // 有效!
# 跨浏览器的事件处理程序
- 跨浏览器的事件处理程序,就是自定义的方法,兼容不同浏览器对处理事件程序的差别。
var EventUtil = {
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;
}
}
};
// 调用示例
var btn = document.getElementById('myBtn');
var handler = function() {
alert('Clicked');
};
EventUtil.addHandler(btn, 'click', handler);
//这里省略了其他代码
EventUtil.removeHandler(btn, 'click', handler);
# 阻止事件传播和默认事件
阻止事件流的传播和阻止事件的默认行为都需要利用事件对象,即 event 对象。
prevnetDefault()
:阻止特定事件的默认行为。只有(事件对象的)cancelable 属性设置为 true 的事件,才可以使用 preventDefault()来取消默认事件。stopPropagation()
:用于立即停止事件在 DOM 层次中的传播,即取消进一步的事件捕获或冒泡。