1 事件处理
1.1 事件概述
在学习事件前,有几个重要的概念需要了解:
- 事件
- 事件处理程序
- 事件驱动式
- 事件流
事件
可被理解为是JavaScript侦测到的行为。
这些行为指的就是页面的加载、鼠标单击页面、鼠标滑过某个区域等。
事件处理程序
指的就是JavaScript为响应用户行为所执行的程序代码。
用户单击button按钮,这个行为就会被JavaScript中的click事件侦测到;然后让其自动执行,为click事件编写的程序代码,如在控制台输出“按钮被单击”。
事件驱动式
是指在Web页面中JavaScript的事件,侦测到的用户行为,并执行相应的事件处理程序的过程。
鼠标移入文本区域,文本区域变色这一过程。
事件流
事件发生时,会在发生事件的元素节点与DOM树根节点之间按照特定的顺序进行传播,这个事件传播的过程就是事件流。
网景(Netscape)提出了“事件捕获方式”、微软(Microsoft)提出了“事件冒泡方式”。
-
事件捕获方式(网景):事件流传播的顺序应该是从DOM树的根节点到发生事件的元素节点。
-
事件冒泡方式(微软):事件流传播的顺序应该是从发生事件的元素节点到DOM树的根节点。
W3C的解决方案
- 规定事件发生后,先实现事件捕获,但不会对事件进行处理。
- 接着进行到目标阶段,执行当前元素对象的事件处理程序,但它会被看成是冒泡阶段的一部分。
- 最后实现事件的冒泡,逐级对事件进行处理。
1.2 事件的绑定方式
事件绑定指的是为某个元素对象的事件绑定事件处理程序。
- 行内绑定式
- 动态绑定式
- 事件监听式
行内绑定式
事件的行内绑定式是通过HTML标签的属性设置实现的。
<标签名 事件="事件的处理程序">
- 标签名可以是任意的HTML标签,如
<div>
标签、<button>
标签等; - 事件是由on和事件名称组成的一个HTML属性,如单击事件对应的属性名为onclick;
- 事件的处理程序指的是JavaScript代码,如匿名函数等。
由于开发中提倡JavaScript代码与HTML代码相分离。因此,不建议使用行内式绑定事件。
动态绑定式
JavaScript代码与HTML代码混合编写的问题。
在JavaScript代码中,为需要事件处理的DOM元素对象,添加事件与事件处理程序。
DOM元素对象.事件 = 事件的处理程序;
事件的处理程序一般都是匿名函数或有名的函数。
行内绑定式与动态绑定式的异同
不同点:
- 实现语法不同,前者通过HTML标签的属性设置,后者在JS中处理DOM对象。
- 事件处理程序中关键字this的指向也不同。前者指向window对象,后者指向当前正在操作的DOM元素对象。
相同点:
- 同一个DOM对象的同一个事件只能有一个事件处理程序。
事件监听式
同一个DOM对象的同一个事件只能有一个事件处理程序,即可给同一个DOM对象的同一个事件添加多个事件处理程序。
实现方式有两种,具有兼容性问题,一类是早期版本的IE浏览器(如IE6~8),一类遵循W3C标准的浏览器(以下简称标准浏览器)。
// 早期版本的IE浏览器
DOM对象.attachEvent(type, callback);
- 参数type指的是为DOM对象绑定的事件类型,它是由on与事件名称组成的,如onclick。
- 参数callback表示事件的处理程序。
// 标准浏览器
DOM对象.addEventListener(type, callback, [capture]);
- 参数type指的是DOM对象绑定的事件类型,它是由事件名称设置的,如click。
- 参数callback表示事件的处理程序。
- 参数capture默认值为false,表示在冒泡阶段完成事件处理,将其设置为true时,表示在捕获阶段完成事件处理。
事件监听式的两种不同实现方式的区别
- 实现的语法不同。
- 事件处理程序的触发顺序也不相同,同一个对象的相同事件,早期版本IE浏览器的事件处理程序按照添加的顺序倒序执行。而标准浏览器的事件处理程序按照添加顺序正序执行。
事件监听的处理程序是一个有名的函数时,可移出事件监听。
- DOM对象.detachEvent(type, callback); // 早期版本IE浏览器
- DOM对象.removeEventListener(type, callback); // 标准浏览器
参数type值的设置要与添加事件监听的事件类型相同,参数callback表示事件处理程序的名称,即函数名。
2 事件对象
2.1 获取事件对象
当发生事件时,都会产生一个事件对象event。
这个对象中包含着所有与事件相关的信息,包括发生事件的DOM元素、事件的类型以及其他与特定事件相关的信息。
比如,因鼠标移动发生事件时,事件对象中就会包括鼠标位置(横纵坐标)等相关的信息;
获取事件对象的方式
- 早期IE浏览器(IE6~8):window.event
- 标准浏览器:会将一个event对象直接传入到事件处理程序中。
var event = e || window.event;
2.2 常用属性和方法
在事件发生后,事件对象event中不仅包含着与特定事件相关的信息,还会包含一些所有事件都有的属性和方法。
分类 | 属性/方法 | 描述 |
---|---|---|
公有的 | type | 返回当前事件的类型,如click |
标准浏览器事件对象 | target | 返回触发此事件的元素(事件的目标节点) |
标准浏览器事件对象 | currentTarget | 返回其事件监听器触发该事件的元素 |
标准浏览器事件对象 | bubbles | 表示事件是否是冒泡事件类型 |
标准浏览器事件对象 | cancelable | 表示事件是否取消默认动作 |
标准浏览器事件对象 | eventPhase | 返回事件传播的当前阶段。1表示捕获阶段,2表示处于目标阶段,3表示冒泡阶段 |
标准浏览器事件对象 | stopPropagation() | 阻止事件冒泡 |
标准浏览器事件对象 | preventDefault() | 阻止默认行为 |
早期版本IE浏览器事件对象 | srcElement | 返回触发此事件的元素(事件的目标节点) |
早期版本IE浏览器事件对象 | cancelBubble | 阻止事件冒泡,默认为false表示允许,设置true表示阻止 |
早期版本IE浏览器事件对象 | returnValue | 阻止默认行为,默认为true表示允许,设置false表示阻止 |
var btn = document.getElementById('btn');
btn.onclick = function(e) {
var obj = event.target || window.event.srcElement;
console.log(obj.nodeName);
console.log(obj.id);
console.log(obj.className);
console.log(obj.innerText);
};
// 事件冒泡
red.onclick = function() {
console.log('red'); };
green.onclick = function() {
console.log('green'); };
yellow.onclick = function() {
console.log('yellow'); };
// 阻止事件冒泡
if (window.event) {
// 早期IE浏览器
window.event.cancelBubble = true;
} else {
// 标准浏览器
e.stopPropagation();
}
HTML中有些元素标签拥有一些特殊的行为。例如,单击 <a>
标签后,会自动跳转到href属性指定的URL链接;单击表单的submit按钮后,会自动将表单数据提交到指定的服务器端页面处理。因此,我们把标签具有的这种行为称为默认行为。
<a id="test" href="http://www.example.com">默认链接</a>
<script>
document.getElementById('test').onclick = function(e) {
if (window.event) {
// 早期版本IE浏览器
window.event.returnValue = false;
} else {
//标准浏览器
e.preventDefault();
}
};
</script>
2.3 练习作业
- 缓动的小球
- 动画特效:是JavaScript的常见功能之一。
- 缓动的实现原理:通过定时器连续的修改当前DOM元素的某个样式值,达到一个动态的特效。
- 缓动动画公式:
- 计算每次缓动的步长 step = ( target - leader ) / 10
- 计算下次的起始点 leader = leader + step
- target 表示目标点。
- leader 表示起始点。
- step 表示从起始点到目标点每次缓动的步长。而缓动特效在实现时,随着距离 target 越来越近,step 步长值逐渐变小,从而达到非常逼真的缓动效果。
- 利用
<div>
设计小球,并用 CSS 设置小球的定位。 - 为小球绑定单击事件,在处理函数中调用自定义的 animate() 实现小球的缓动。
- 编写 animate() 动画函数,在函数中利用定时器,根据缓动公式完成缓动动画。
3 事件分类
3.1 页面事件
HTML页面是按照什么样的顺序进行加载的?
页面的加载是按照代码的编写顺序,从上到下依次执行的。
会出现的问题:若在页面还未加载完成的情况下,就使用JavaScript操作DOM元素,会出现语法错误。
<!-- 页面加载顺序的问题-->
<script>
document.getElementById('demo').onclick = function () {
console.log('单击');
};
</script>
<div id="demo"></div>
解决办法:页面事件可以改变JavaScript代码的执行时机。
- load事件:用于body内所有标签都加载完成后才触发,又因其无需考虑页面加载顺序的问题,常常在开发具体功能时添加。
- unload事件:用于页面关闭时触发,经常用于清除引用避免内存泄漏时使用。
window.onload = function() {
// JavaScript代码
};
3.2 焦点事件
在Web开发中,焦点事件多用于表单验证功能,是最常用的事件之一。
例如,文本框获取焦点改变文本框的样式,文本框失去焦点时验证文本框内输入的数据等。
事件名称 | 事件触发时机 |
---|---|
focus | 当获得焦点时触发(不会冒泡) |
blur | 当失去焦点时触发(不会冒泡) |
3.3 鼠标事件
鼠标事件是Web开发中最常用的一类事件。
例如,鼠标滑过时,切换Tab栏显示的内容;利用鼠标拖拽曳状态框,调整它的显示位置等,这些常见的网页效果都会用到鼠标事件。
事件名称 | 事件触发时机 |
---|---|
click | 当按下并释放任意鼠标按键时触发 |
dblclick | 当鼠标双击时触发 |
mouseover | 当鼠标进入时触发 |
mouseout | 当鼠标离开时触发 |
change | 当内容发生改变时触发,一般多用于 <select> 对象 |
mousedown | 当按下任意鼠标按键时触发 |
mouseup | 当释放任意鼠标按键时触发 |
mousemove | 在元素内当鼠标移动时持续触发 |
在项目开发中还经常涉及一些常用的鼠标属性,用来获取当前鼠标的位置信息。
位置属性(只读) | 描述 |
---|---|
clientX | 鼠标指针位于浏览器页面当前窗口可视区的水平坐标(X轴坐标) |
clientY | 鼠标指针位于浏览器页面当前窗口可视区的垂直坐标(Y轴坐标) |
pageX | 鼠标指针位于文档的水平坐标(X轴坐标),IE6~8不兼容 |
pageY | 鼠标指针位于文档的垂直坐标(Y轴坐标),IE6~8不兼容 |
screenX | 鼠标指针位于屏幕的水平坐标(X轴坐标) |
screenY | 鼠标指针位于屏幕的垂直坐标(Y轴坐标) |
IE68浏览器中不兼容pageX和pageY属性。因此,项目开发时需要对IE68浏览器进行兼容处理。
var pageX = event.pageX || event.clientX + document.documentElement.scrollLeft;
var pageY = event.pageY || event.clientY + document.documentElement.scrollTop;
鼠标在文档中的坐标等于鼠标在当前窗口中的坐标加上滚动条卷去的文本长度。
3.4 作业练习
-
鼠标拖曳特效
- 盒子的位置(left和top值)= 鼠标的位置(left和top值)- 鼠标按下时与盒子之间的距离(left和top值)。
- 编写HTML,设计弹框用于实现拖拽特效。
- 为拖拽条添加mousedown事件及其处理程序。
- 处理鼠标移动事件,实现鼠标的拖拽的特效。
- 处理释放鼠标按键的事件,实现鼠标按钮松开后,弹框不再移动。
3.5 键盘事件
键盘事件是指用户在使用键盘时触发的事件。
例如,用户按Esc键关闭打开的状态栏,按Enter键直接完成光标的上下切换等。
事件名称 | 事件触发时机 |
---|---|
keypress | 键盘按键(Shift、Fn、CapsLock等非字符键除外)按下时触发 |
keydown | 键盘按键按下时触发 |
keyup | 键盘按键弹起时触发 |
keypress事件保存的按键值是ASCII码,keydown和keyup事件保存的按键值是虚拟键码。
3.6 表单事件
表单事件指的是对Web表单操作时发生的事件。
例如,表单提交前对表单的验证,表单重置时的确认操作等。JavaScript提供了相关的表单事件。
事件名称 | 事件触发时机 |
---|---|
submit | 当表单提交时触发 |
reset | 当表单重置时触发 |
4 练习作业
- 图片放大特效
- 准备两张相同的图片,小图和大图。
- 小图显示在商品的展示区域。
- 大图用于鼠标在小图上移动时,按比例的显示大图中的对应区域。
- 编写HTML页面,展示小图、隐藏鼠标的遮罩及大图。
- 当鼠标在小图上移动时,显示鼠标的遮罩和大图。
- 当鼠标移动时,让遮罩跟着在小图中进行移动。
- 限定遮罩在小图中的可移动范围。
- 根据遮罩在小图中的覆盖范围,按比例的显示大图。
的确认操作等。JavaScript提供了相关的表单事件。
事件名称 | 事件触发时机 |
---|---|
submit | 当表单提交时触发 |
reset | 当表单重置时触发 |
4 练习作业
- 图片放大特效
- 准备两张相同的图片,小图和大图。
- 小图显示在商品的展示区域。
- 大图用于鼠标在小图上移动时,按比例的显示大图中的对应区域。
- 编写HTML页面,展示小图、隐藏鼠标的遮罩及大图。
- 当鼠标在小图上移动时,显示鼠标的遮罩和大图。
- 当鼠标移动时,让遮罩跟着在小图中进行移动。
- 限定遮罩在小图中的可移动范围。
- 根据遮罩在小图中的覆盖范围,按比例的显示大图。