事件是什么,可以用来做什么,什么时候用到它?
事件,就是文档或浏览器窗口中发生的一些特定的交互瞬间。JavaScript与HTML之间的交互是通过事件实现的
事件流
事件流描述的是从页面中接收事件的顺序
事件冒泡(event bubbling)
事件开始时由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播到较为不具体的节点(文档)
事件捕获(event capturing)
document对象首先接收到事件,然后事件沿DOM树依次向下,一直传播到事件的实际目标
DOM事件流
“DOM2级事件”规定的事件流包括三个阶段:事件捕获阶段、处于目标阶段和事件冒泡阶段
在DOM事件流中,实际的目标在捕获阶段不会接收到事件,目标的事件处理被看成冒泡阶段的一部分。但IE9、Safari、Chrome、FireFox和Opera9.5及更高版本都会在捕获阶段触发事件对象上的事件。结果,就是有两个机会在目标对象上面操作事件。
事件处理程序
响应某个事件的函数叫做事件处理程序(或事件侦听器)
HTML事件处理程序
某个元素支持的每种事件,都可以使用一个与相应事件处理程序同名的HTML特性来指定。这个特性的值应该是能够执行JavaScript代码
或
this值等于事件的目标元素
一般很少使用HTML事件处理程序,原因是它有如下几个缺点:
- 有调用顺序的要求,事件函数必须在HTML之前定义好
- 扩展事件处理程序的作用域在不同浏览器中会导致不同结果
- HTML和JavaScript代码紧密耦合,如果要更换事件处理程序,就要改动两个地方
DOM0级事件处理程序
var btn = document.getElementById("myBtn");
//绑定事件
btn.onclick = function() {
alert(this.id); //"myBtn"
};
//解绑事件
btn.onclick = null;
作用域:依附的元素的作用域
DOM2级事件处理程序
“DOM2级事件”定义了两个方法,用于处理指定和删除事件处理程序的操作:addEventListener() 和 removeEventListener()
所有节点中都包含这两个方法,并且它们都接受3个参数:要处理的事件名、作为事件处理程序的函数和一个布尔值(true表示在捕获阶段调用事件处理程序/false表示在冒泡阶段调用事件处理程序)
使用DOM2级方法添加事件处理程序的主要好处是可以添加多个事件处理程序,依次顺序触发
作用域:依附的元素的作用域
IE事件处理程序
IE实现了与DOM中类似的两个方法:attachEvent()和detachEvent(),由于IE8及更早版本只支持事件冒泡,所以通过attachEvent()添加的事件处理程序都会被添加到冒泡阶段
同addEventListener(),attachEvent()方法也可以用来为一个元素添加多个事件处理程序,不同的是以相反的顺序被触发
作用域:全局作用域
跨浏览器的事件处理程序
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.removeHandler) {
element.removeHandler(type, handler, false);
} else if(element.detachEvent) {
element.detachEcent("on" + type, handler);
} else {
element["on" + type] =null;
}
}
};
事件对象
在触发DOM上的某个事件时,会产生一个事件对象event,这个对象中包含着所有与事件有关的信息。包括导致事件的元素、事件的类型以及其他与特定事件相关的信息。
DOM中的事件对象
无论指定事件处理程序时使用什么方法(DOM0级或DOM2级),都会传入event对象,event对象包含与创建它的特定事件有关的属性和方法,触发的事件类型不一样,可用的属性和方法也不一样。不过,所有事件都会有下列属性和方法:
bubbles
cancelable
currentTarget
defaultPrevented
detail
eventPhase
preventDefault()
stopImmediatePropagation()
stopPropagation()
target
trusted
type
view
具体含义看这里
在事件处理程序内部,对象this始终等于currentTarget的值,而target则只包含事件的实际目标
IE中的事件对象
DOM0级:event对象作为window对象的一个属性存在
attachEvent():event对象作为参数被传入事件处理函数中,也可以通过window对象来访问event对象
IE的event对象同样也包含与创建它的事件相关的属性和方法。其中很多属性和方法都有相应的或者相关的DOM属性和方法,但所有事件对象都会包含下列属性和方法:
cancelBubble
returnValue
srcElement
type
跨浏览器的事件对象
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;
}
},
getEvent: function(event) {
return event ? event : window.event;
},
getTarget: function(event) {
return event.target || event.srcElement;
},
preventDefault: function() {
if(event.preventDefault) {
event.preventDefault();
} else {
event.returnValue = false;
}
},
removeHandler: function(element, type, handler) {
if(element.removeHandler) {
element.removeHandler(type, handler, false);
} else if(element.detachEcent) {
element.detachEvent("on" + type, handler);
} else {
element["on" + type] =null
}
},
stopPropagation: function(event) {
if(event.stopPropagation) {
event.stopPropagation();
} else {
event.cancelBubble = true;
}
}
};
事件类型
“DOM3级事件”规定了以下几类事件:
- UI(User Interface,用户界面)事件,当用户和页面上的元素交互时触发;
- 焦点事件,当元素获取或失去焦点时触发;
- 鼠标事件,当用户通过鼠标在页面上执行操作时触发;
- 滚轮事件,当使用鼠标滚轮(或类似设备)时触发;
- 文本时间,当在文档中输入文本时触发;
- 键盘事件,当用户通过键盘在页面上执行操作时触发;
- 合成事件,当为IME(Input Method Editor,输入法编辑器)输入字符时触发;
- 变动(mutation)事件,当底层DOM结构发生变化时触发;
- 变动名称事件,当元素或属性名变动时触发。(已废弃)
UI事件
DOMActive
(DOM3已废弃该事件)load
unload
abort
error
select
resize
scroll
可以使用document.implementation.hasFeature("HTMLEvents", "2.0");
来确定浏览器是否支持“DOM2级事件”;使用document.implementation.hasFeature("UIEvent", "3.0");
来确定是否支持“DOM3级事件”
-
load
事件
当页面完全加载后(包括所有图像、JavaScript文件、CSS文件等外部资源),就会触发window上面的load事件;
上面也可以触发load事件,无论是在DOM中的图像元素还是HTML中的图像元素。注意,新图像元素不一定要从添加到文档后才开始下载,只要设置了src属性就会开始下载;