JavaScript和HTML的交互是通过事件实现的。
事件就是用户或浏览器自身执行的某种动作。
举几个可能发生的不同事件:
- 用户在某个元素上点击鼠标或悬停光标。
- 用户在键盘中按下某个按键。
- 用户调整浏览器的大小或者关闭浏览器窗口。
- 一个网页停止加载。
- 提交表单。
- 播放、暂停、关闭视频。
- 发生错误。
事件流
事件流描述的是从页面中接收事件的顺序。
当我们单击网页上的一个div块的时候,单击事件会仅仅作用在这个div上面吗?在浏览器发展到第四代时,IE和Netscape的开发团队都遇到这个问题,他们都一致认为,除了单击div块,我们也单击了body、 html、甚至是整个document,但不幸的是两个团队针对事件流模型产生了两个完全相反的概念。
- 事件冒泡
IE的事件流称为事件冒泡。
即:事件由最具体的元素接收(div),逐级向上传播到不具体的节点(document)。
- 事件捕获
Netscape提出的事件流模型称为事件捕获。
即:事件从最不具体的节点开始接收(document),传递至最具体的节点<div>,和IE的冒泡刚好相反, 事件捕获的本意是当事件到达预定目标前捕获它。
- DOM2级事件流
为了能够兼容上述两种事件模型,又提出了一个DOM2级事件模型,它规定了事件流包含三个阶段:
1. 事件捕获阶段:为事件捕获提供机会;
2. 处于目标阶段:事件的目标接收到事件(但并不会做出响应);
3. 事件冒泡阶段:事件响应阶段;
事件处理程序(事件处理器)
每个可用的事件都会有一个事件处理器,也就是事件触发时会运行的代码块。当我们定义了一个用来回应事件被激发的代码块的时候,我们说我们注册了一个事件处理器。注意:事件处理器有时候被叫做事件监听器——从我们的用意来看这两个名字是相同的,尽管严格地说来这块代码既监听也处理事件。监听器留意事件是否发生,然后处理器就是对事件发生做出的回应。
事件就是用户或浏览器自身执行的某种动作,比如click、load、mouseover等,都是事件类型(俗称事件名称),而响应某个事件的方法就叫做事件处理程序或者事件监听器。
- HTML内联方式(不推荐,慎用)
元素支持的每个事件都可以使用一个相应事件处理程序同名的HTML属性指定。这个属性的值应该是可以执行的JavaScript代码,我们可以为一个button添加click
事件处理程序。
<input type="button" value="Click Here" onclick="alert('Clicked!');" />
- JavaScript指定事件处理程序
通过JavaScript指定事件处理程序就是把一个方法赋值给一个元素的事件处理程序属性。
<input id="btnClick" type="button" value="Click Here" />
<script type="text/javascript">
var btnClick = document.querySelector("#btnClick");
btnClick.onclick = function showMessage() {
alert(this.id);
};
</script>
-
DOM2事件处理程序
DOM2级事件定义了两个方法用于处理指定和删除事件处理程序的操作:
- addEventListener
- removeEventListener
所有的DOM节点都包含这两个方法,并且它们都接受三个参数:
- 事件类型
- 事件处理方法
- 布尔参数,如果是true表示在捕获阶段调用事件处理程序,如果是false,则是在事件冒泡阶段处理,默认是false。
<input id="btnClick" type="button" value="Click Here" />
<script type="text/javascript">
var btnClick = document.querySelector("#btnClick");
btnClick.addEventListener('click', function() {
alert(this.id);
}, false);
</script>
事件对象
在触发DOM的事件时候,会产生一个事件对象Event。这个对象包含着所有与事件相关的信息,包括产生事件的元素、事件类型等相关信息。所有浏览器都支持event对象,但是支持方式不同。
1. DOM中的事件对象
<script type="text/javascript">
var btnClick = document.querySelector("#btnClick");
btnClick.addEventListener('click', function(e) {
console.log(e);
}, false);
</script>
结果是一个event对象,event对象包含与创建它的特定事件有关的属性和方法,触发事件的类型不同,可用的属性和方法也不同,但是所有事件都会包含下面的属性
属性/方法 | 类型 | 含义 |
---|---|---|
bubbles | Boolean | 事件是否冒泡 |
cancelable | Boolean | 是否可以取消事件的默认行为 |
currentTarget | Element | 事件处理程序当前处理元素 |
detail | Integer | 与事件相关细节信息 |
eventPhase | Integer | 事件处理程序阶段:1.捕获阶段,2.处于目标阶段,3.冒泡 |
preventDefault() | Function | 取消事件的默认行为 |
stopPropagation() | Function | 取消事件进一步捕获或者冒泡 |
target | Element | 事件的目标元素 |
type | String | 被触发的事件类型 |
view | AbstractView | 与事件关联的抽象视图,等同于发生事件的window对象 |
在事件处理程序内部,this
等同于currentTarget
,target
是事件的实际目标(参考事件代理来理解)。
要阻止事件的默认行为,可以使用preventDefault()
,前提是cancelable为true
stopPropagation()方法可以停止事件在DOM层次中的传播,即取消进一步的事件捕获或冒泡
2. IE中的事件对象
访问IE的event对象有几种不同的方式,取决于指定事件处理程序的方法。
- 直接为DOM元素添加事件处理程序时,event对象作为window对象的一个属性存在。
var handler = function () {
var e = window.event;
alert(e.type);
}
var btnClick = document.getElementById('btnClick');
btnClick.onclick = handler;
- 通过attachEvent添加事件处理程序时,event对象会传入事件处理程序,这时候也可以使用window对象访问event对象。
var handler = function (e) {
alert(e.type);
}
var btnClick = document.getElementById('btnClick');
attachEvent(btnClick, handler);
IE中所有的事件都包含以下属性方法
属性/方法 | 类型 | 说明 |
---|---|---|
cancelBubble | Boolean | 默认为false,设置为true可以取消事件冒泡 |
returnVlaue | Boolean | 默认为true,设置为false可以取消事件默认行为 |
srcElement | Element | 事件的目标元素 |
type | String | 被触发的事件类型 |
阻止事件默认行为
var link = document.querySelector("#link");
link.addEventListener("click",function(e){
e.preventDefault();
});