事件流
严格来说,上图还少了一个层级window,在顶层。
DOM2级 与 DOM0级相比
1、可以绑定多个监听函数,而DOM0级只能绑定一个监听函数。
2、提供了移除的方法,但对于匿名函数无效。
3、可以控制捕获还是冒泡,DOM0级只有冒泡。
事件对象e的常用属性方法
e.stopImmediatePropagation()
如果注册了多个监听函数,则一并阻止冒泡。
e.currentTarget
绑定时间的对象,始终与this相同。
e.target
触发事件的是哪个元素,就显示哪个元素对象。
mouseenter/mouseleave与mouseover/mouseout的区别
1、mouseenter/mouseleave
把冒泡机制阻止了。
2、mouseenter/mouseleave
运用了relatedTarget
属性(e.relatedTarget
既不是目标元素,也不是目标元素的子元素)。
e.target与e.relatedTarget常用事件
事件名称 target属性 relatedTarget属性
focusin 接受焦点的节点 丧失焦点的节点
focusout 丧失焦点的节点 接受焦点的节点
mouseenter 将要进入的节点 将要离开的节点
mouseleave 将要离开的节点 将要进入的节点
mouseout 将要离开的节点 将要进入的节点
mouseover 将要进入的节点 将要离开的节点
dragenter 将要进入的节点 将要离开的节点
dragexit 将要离开的节点 将要进入的节点
自定义事件
自定义事件不是由DOM原生触发的,它的目的是让开发人员创建自己的事件。
Event()
最简单的就是使用Event()构造函数。
CustomEvent()
如果需要在触发事件的同时,传入指定的数据,需要使用CustomEvent构造函数生成自定义的事件对象。
用this.dispatchEvent(customEvent(this))
触发。
异步类型
一般而言,异步任务有以下三种类型:
1、普通事件,如click、resize等
2、资源加载,如load、error等
3、定时器,包括setInterval、setTimeout等
同步变异步是性能优化的手段之一,如利用定时器对数组进行分块。
事件对象e的坐标位置
clientX/Y与x/y
clientX/Y
表示鼠标指针在可视区域中的水平和垂直坐标。
screenX/Y
screenX/Y
表示鼠标指针相对于屏幕的水平和垂直坐标
PageX/Y
与layerX/Y
pageX/Y
表示相对于页面的水平和垂直坐标,它与clientX/clientY的区别是不随滚动条的位置变化。
offsetX/Y
offsetX/Y
表示相对于定位父级的水平和垂直坐标。
当页面无定位元素时,body是元素的定位父级。由于body的默认margin是8px,所以offsetX/Y与clientX/Y
差(8,8)。
时间间隔
系统为了防止按键误被连续按下,所以在第一次触发keydown
事件后,有500ms的延迟,才会触发第二次keydown
事件。
[注意]类似的,keypress
事件也存在500ms
的时间间隔。
顺序
如果用户一直按键不松开,就会连续触发键盘事件,触发的顺序如下
1、keydown
2、keypress
3、keydown
4、keypress
5、(重复以上过程) 6、keyup
。
变动事件mutation
7个变动事件,浏览器兼容性都不是太好。说的过得去就是DOMNodeInserted
、DOMNodeRemoved
和DOMSubtreeModified
这三个事件,不兼容IE8-浏览器。
剪贴板操作包括剪切(cut)、复制(copy)和粘贴(paste)这三个操作,快捷键分别是ctrl+x、ctrl+c、ctrl+v。当然也可以使用鼠标右键菜单进行操作。
如果DOM结构发生变化,触发的是变动事件,如果文本框中的文本发生变化,触发的是文本事件。
change
说起文本变化,最先想到的可能就是change事件。
对于和
元素,在它们失去焦点且value值改变时触发;对于
元素,在其选项改变时触发。
textInput
DOM3级事件引人了一个新事件——textInput
,用来替代keypress
事件。当用户在可编辑区域中输入字符时,就会触发这个事件。
[注意]该事件只支持DOM2级事件处理程序,且只有chrome和safari浏览器支持。
由于的游标并不是可编辑区域,所以,
textInput
事件对游标变化无作用。
input
文本事件中,除了textInput事件,还有一个input事件。
HTML5新增了一个input事件,只要输入框内容发生变化就会立即触发,但通过JS改变value时不会触发。
所以这事件与change事件的区别就是不需要移除焦点就可以触发。
该事件可以在chrome/safari/firefox/IE9浏览器中,实时监测游标的变化。
加载事件
load
如果页面从浏览器缓存加载,并不会触发load事件,图像和框架iframe也可以触发load事件。
要在指定图像的src属性之前先指定事件,图像是从设置src属性之后开始下载。
script元素也可以触发load事件,以便开发人员确定动态加载的JS文件是否加载完毕。与图像不同,只有在设置了script元素的src属性并将该元素添加到文档后,才会开始下载JS文件。换句话说,指定src属性和指定事件处理程序的先后顺序不重要。
类似地,link元素可以触发load事件,且无兼容性问题。与script类似,在未指定href属性并将link元素添加到文档之前也不会开始下载样式表。
error
load事件在加载成功时触发,而error事件与之正相反,在加载失败时触发。凡是可以触发load事件的元素,同样可以触发error事件。
任何没有通过try-catch处理的错误都会触发window对象的error事件。
error事件可以接收三个参数:错误消息、错误所在的URL和行号。多数情况下,只有错误消息有用,因为URL只是给出了文档的位置,而行号所指的代码行既可能出自嵌入的JS代码,也可能出自外部的文件。
要指定onerror事件处理程序,可以使用DOM0级技术,也可以使用DOM2级事件的标准格式。
这个事件处理程序是避免浏览器报告错误的最后一道防线。理想情况下,只要可能就不应该使用它。只要能够适当地使用try-catch语句,就不会有错误交给浏览器,也就不会触发error事件。
图像也支持error事件。只要图像的src特性中的URL不能返回可以被识别的图像格式,就会触发error事件。此时的error事件遵循DOM格式,会返回一个以图像为目标的event对象。
发生error事件时,图像下载过程已经结束,也就是不能再重新下载了。但是,可以在error事件中,重新设置图像的src属性,指向备用图像的地址。
abort
元素加载中止时,(如加载过程中按下ESC键,停止加载),触发该事件,常用于图片加载。
unload
与load事件对应的是unload事件,该事件在文档被完全卸载后触发,刷新页面时,也会触发该事件。
在卸载页面的时候,会导致“空事件处理程序”的发生。“空事件处理程序”是指内存中存留的过时不用的事件处理程序,它们是造成Web应用程序内存与性能问题的主要原因。一般来说,最好的做法是在页面卸载之前,先通过onunload事件处理程序移除所有事件处理程序。因此,只要是通过onload事件处理程序添加的东西,最后都应该通过onunload事件处理程序将它们移除。
beforeunload
beforeunload事件在关闭网页或刷新网页时触发。它一般地用来防止用户不小心关闭网页。
DOMContentLoaded
DOMContentLoaded
事件则在形成完整的DOM树之后就会触发,而不理会图像、JS文件、CSS文件或其他资源是否下载完毕。与load事件不同,DOMContentLoaded
支持在页面下载的早期添加事件处理程序,这也就意味着用户能够尽早地与页面进行交互。
[注意]网页的JS脚本是同步执行的,所以定义DOMContentLoaded事件的监听函数,应该放在所有脚本的最前面。否则脚本一旦发生堵塞,将推迟触发DOMContentLoaded
事件。
readystatechange
readystatechange
事件发生在Document对象和XMLHttpRequest对象,它们的readyState
属性发生变化时触发。
焦点管理
activeElement
document.activeElement
属性用于管理DOM焦点,保存着当前获得焦点的元素。
获得焦点
元素获得焦点的方式有4种,包括页面加载、用户输入(按tab键)、focus()方法和autofocus属性。
【1】页面加载
默认情况下,文档刚刚加载完成时,document.activeElement
中保存的是body元素的引用。文档加载期间,document.activeElement
的值为null。
【2】用户输入(按tab键)
用户通常可以使用tab键移动焦点,使用空格键激活焦点。比如,如果焦点在一个链接上,此时按一下空格键,就会跳转到该链接。
1、如果tabindex=-1,tab键跳过当前元素。
2、如果tabindex=0,表示tab键将遍历当前元素。如果一个元素没有设置tabindex,默认值就是0。
3、如果tabindex大于0,表示tab键优先遍历。值越大,就表示优先级越小
下列代码中,使用tab键时,button获得焦点的顺序是2、5、1、3