事件

JavaScript 与 HTML 之间的交互是通过事件实现的。事件,就是文档或浏览器窗口中发生的一些特定的交互瞬间。可以使用侦听器(或处理程序)来预订事件,以便事件发生时执行相应的代码。

事件流

事件

事件冒泡

IE 的事件流叫做事件冒泡,即事件开始由最具体的元素接收,然后逐级向上传播到较为不具体的节点(文档)。所有现代浏览器都支持事件冒泡。

事件捕获

事件捕获的思想是不太具体的节点应该更早接收事件。而最具体的节点应该最后接收到事件。

DOM事件流

“DOM2级事件”规定的事件流包括三个阶段:事件捕获阶段、处于目标阶段和事件冒泡阶段。首先发生的是事件捕获,为截获事件提供了机会。然后是实际的目标接受度额事件。最后一个阶段是冒泡阶段,可以在这个阶段对事件做出响应。

事件处理程序

事件就是用户或浏览器自身执行的某种动作。而响应某个事件的函数就叫做事件处理程序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// HTML 事件处理程序
// <input type="button" value="Click Me" onclick="alert('clicked')">
//DOM0 级事件处理程序
div.onclick = function(){ alert('clicked') };
//DOM2 级事件处理程序
//接收3个参数:要处理的事件名、作为事件处理程序的函数和一个布尔值。最后一个参数为true,捕获阶段执行;反之,在冒泡阶段执行。
div.addEventListener();
div.removeEventListener();
//IE事件处理程序
//接收2个参数:事件处理程序名称与事件处理程序函数。只支持冒泡。第一个参数需要带'on',如'onclick';
div.attachEvent();
div.detachEvent();

事件对象

在触发 DOM 上的某个事件时,会产生一个事件对象 event,这个对象中包含着所有与事件有关的信息。包括导致事件的元素、事件的类型以及其他与特定事件相关的信息。

下面是一些事件对象的属性和方法:

属性/方法 说明
bubbles 表明事件是否冒泡
cancelable 是否可以取消事件默认行为
currentTarget 事件处理程序当前正在处理事件的那个元素
defaultPrevented 值为true时表明调用了preventDefault()
detail 与事件相关的细节信息
eventPhase 事件的阶段,1捕获,2目标,3冒泡
preventDefault() 取消事件的默认行为
stopImmediatePropagation() 取消事件的进一步捕获和冒泡,同时阻止任何事件处理程序被调用
stopPropagation 取消事件的进一步捕获和冒泡
target 事件目标
trusted 为true表示事件是浏览器生成的
type 被触发的事件类型
view 与事件有关的抽象视图

在事件处理程序内部,对象 this 始终等于 currentTarget 的值,而 target 则只包含事件的实际目标。如果直接将事件处理程序指定给了目标元素,则 this、currentTarget 和 target 包含相同的值。

1
2
event.preventDefault(); //阻止浏览器默认行为
event.stopPropagation(); //阻止冒泡

IE 中的事件对象

属性/方法 说明
cancelBubble 默认为false,设为true就可以取消事件冒泡
srcElement 事件的目标(与DOM中的target相同)
type 被触发的事件类型

事件类型

不同的事件类型具有不同的信息,而“DOM3级事件”规定了以下几类事件:

  • UI事件,当用户与页面上的元素交互时触发
  • 焦点事件
  • 滚轮事件
  • 文本事件
  • 键盘事件
  • 合成事件,当为输入法编辑器输入字符时触发
  • 变动事件,当底层DOM结构发生变化时触发

UI事件

1
2
3
4
load //页面完全加载后触发
unload //文档被完全卸载后触发
resize //浏览器窗口尺寸调成时触发
scroll //页面滚动时触发

焦点事件

1
2
blur //元素失去焦点时触发
focus //元素获取焦点时触发

鼠标和滚轮事件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
click //单击鼠标主键
dblclick //双击鼠标主键
mousedown //按下鼠标任意键
mouseenter //鼠标移入(子元素内不触发)
mouseleave //鼠标移出(子元素内不触发)
mousemove //在元素内移动,重复触发
mouseout //鼠标移出
mouseover //鼠标移入
mouseup //释放鼠标时
DOMMouseScroll //火狐鼠标滚轮事件
mousewheel //IE 和 chrome 滚轮事件
event.clientX //事件发生时,鼠标指针在视口中的水平距离
event.clientY //事件发生时,鼠标指针在视口中的垂直距离
event.pageX //事件发生时,鼠标指针在页面中的水平距离
event.pageY //事件发生时,鼠标指针在页面中的垂直距离
document.body.scrollLeft || document.documentElement.scrollLeft //页面左右滚动距离
document.body.scrollTop || document.documentElement.scrollTop //页面上下滚动距离
screenX //鼠标指针在电脑屏幕中的水平距离
screenY //鼠标指针在电脑屏幕中的垂直距离

修改键

1
2
3
4
e.shiftKey //shift 键被按下时,值为 true。
e.ctrlKey //ctrl 键被按下时,值为 true。
e.altKey //alt 键被按下时,值为 true。
e.metaKey //window 键被按下时,值为 true。

键盘与文本事件

1
2
3
4
5
6
7
8
keydown //按下键盘任意键触发,按住不放会重复触发
keypress //按下键盘字符键触发,按住不放会重复触发
keyup //释放键盘的键时触发
textInput //文本事件
e.keyCode //键码
e.charCode //字符编码,为所代表字符的 ASCII 编码。

HTML5 事件

1
2
3
4
5
6
contextmenu //为 window 添加事件。单击鼠标右键调出上下文菜单。可以通过 e.preventDefault() 阻止默认事件。
beforeunload //为 window 添加事件。页面关闭前触发。为显示弹出对话框,必须将 e.returnValue 的值设为提示文字,同时将提示文字作为函数的值返回。
DOMContentLoaded //为 window 或 document 添加事件。形成完整 DOM 树之后就触发。不理会图像、javascript、css或其他资源是否下载完毕。
readystatechange //为 document 添加事件。事件提供与文档或元素加载状态有关的信息。
pageshow & pagehide //为 window 添加事件
hashchange //为 window 添加事件,此时的 event 对象包含额外的属性:oldURL 和 newURL(有兼容问题,可使用 location 对象代替)。

设备事件

1
2
3
4
orientationchange //屏幕旋转事件(window.orientation)ios 设备支持
MozOrientation //设备方向改变时触发(火狐支持)
deviceorientation //
devicemotion //

触摸与手势事件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
touchstart //触摸屏幕时触发
touchmove //在屏幕上滑动时触发
touchend //从屏幕上移开时触发
//触摸事件还包含下列三个用于跟踪触摸的属性:
touches //表示当前跟踪触发操作的 Touch 对象的数组
targetTouchs //特定于事件对象的 Touch 对象的数组
changeTouches //上次触摸一来发生了什么改变的 Touch 对象数组
//每个 Touch 对象包含下面这些属性
clientX
clientY
pageX
pageY
screenX
screenY
target //触摸的 DOM 节点目标
identifier //标识触摸的唯一 ID

内存和性能

事件委托

事件委托利用了事件冒泡,只指定一个事件处理程序,就可以管理某一类的所有事件。

移出事件处理程序

每当将事件处理程序指定给元素时,运行中的浏览器代码于支持页面交互的 JavaScript 代码之间就会建立一个连接。这种连接越多,页面执行越慢,所以可以在不需要的时候移出事件处理程序。

模拟事件

可以在 document 对象上使用 createEvent() 方法创建 event 对象。这个方法接收一个参数,即表示要创建的事件类型的字符串。这个字符串可以是以下之一:

  • UIEvents: 一般化的 UI 事件(DOM3 中为 UIEvent)
  • MouseEvents: 一般化的鼠标事件(DOM3 中为 MouseEvent)
  • MutationEvents: 一般化的 DOM 变动事件(DOM3 中为 MutationEvent)
  • HTMLEvents: 一般化的 HTML 事件

模拟鼠标事件

初始化事件需要传入下列参数:

type(字符串):要触发的事件类型,例如‘click’。
bubbles(布尔值):表示事件是否应该冒泡,针对鼠标事件模拟,该值应该被设置为true。
cancelable(布尔值):表示该事件是否能够被取消,针对鼠标事件模拟,该值应该被设置为true。
view 抽象视图:事件授予的视图,这个值几乎全是document.defaultView.
detail(整数):附加的事件信息这个初始化时一般应该默认为0。
screenX(整数) :事件距离屏幕左边的X坐标
screenY(整数) :事件距离屏幕上边的y坐标
clientX(整数) :事件距离可视区域左边的X坐标
clientY(整数) :事件距离可视区域上边的y坐标
ctrlKey(布尔值):代表ctrol键是否被按下,默认为false。
altKey(布尔值):代表alt键是否被按下,默认为false。
shiftKey(布尔值):代表shif键是否被按下,默认为false。
metaKey(布尔值):代表meta key 是否被按下,默认是false。
button(整数):表示被按下的鼠标键,默认是零.
relatedTarget(对象):事件的关联对象.只有在模拟mouseover 和 mouseout时用到。

1
2
3
4
5
6
7
8
9
10
var btn = document.getEventById('myBtn');
//创建事件对象
var event = document.createEvent('MouseEvents');
//初始化事件对象
event.initMouserEvent('click', true, true, document.defaultView, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
//触发事件
btn.dispatchEvent(event);

模拟键盘事件

初始化事件需要传入下列参数:

  • type(字符串):表示要触发的事件类型,如’keydown’
  • bubbles(布尔值):表示事件是否应该冒泡
  • cancelable(布尔值):表示事件是否可以取消
  • view:与事件关联的视图
  • key(布尔值):表示按下键的键码
  • location(整数):表示按下了哪里的键
  • modifiers(字符串):空格分割的修改键列表,如’shift’
  • repeat(整数):在一行中按了这个键多少次
1
2
3
4
5
6
7
8
9
10
var textBox = document.getEventById('myTextBox');
//创建事件对象
var event = document.createEvent('keyboardEvent');
//初始化事件对象
event.initMouserEvent('keydown', true, true, document.defaultView, 'a', 0, 'shift', 0);
//触发事件
textBox.dispatchEvent(event);

自定义事件

1
2
3
4
5
6
7
8
9
//initCustomEvent()方法接收四个参数:
//type(字符串): 触发的事件类型,例如‘keydown’
//bubbles(布尔值): 事件是否应该冒泡
//cancelable(布尔值): 事件是否可以取消
//detail(对象): 任意只,保存在 event 对象的 detail 属性中
var event = document.createEvent('CustomEvent');
event.initCustomEvent('myevent', true, false, 'Hello World');
div.dispatchEvent(event);