DOM事件详解(事件与处理程序)
一、JS的三大事件
1)鼠标事件
* click:单击
* dblclick:双击
* mousedown:鼠标按下
* mouseup:鼠标抬起
* mouseenter:鼠标进入
* mouseleave:鼠标离开
* mouseout:鼠标离开
* mouseover:鼠标悬浮
* mousemove:鼠标移动
2)键盘事件
* keydown:键盘按下
* keyup:键盘抬起
* keypress:键盘按下抬起
3)HTML事件
* load:文档加载完成
* select:被选中的时候
* change:内容被改变
* focus:元素获取焦点
* resize:窗口尺寸改变
* scroll:滚动条滚动
二、事件流
1、众所周知,HTML与JavaScript的交互是由事件驱动的,我们定义在某个时刻调用某个事件来完成页面的交互。HTML页面就是一个DOM树,当一个元素调用
一个事件时,该事件会在结点与结点之间传递,而事件流就描述了事件的传递的过程。简言之,事件流就是描述了从页面中接收事件的顺序。
例如:一个父元素中有一个子元素,给这两个元素绑定一个相同的事件,点击时触发。当点击子元素时实际上也触发了父元素,那么是先外层的父元素触发
事件还是内层的子元素先触发呢?这就是事件流要处理的。
2、事件流有两种:事件冒泡流、事件捕获流。(现在主流是事件冒泡流。)
事件冒泡流:具体触发事件的元素先接收事件,然后向上传导
事件捕获流:与冒泡流相反,最外层先接收到事件
3、事件流有三个阶段:事件捕获阶段---->处于目标阶段---->事件冒泡阶段
1)事件捕获阶段:该阶段捕获截获事件:window -> document -> html -> body -> button
注意:DOM2级规定从document开始,不包括事件目标,但是基本上浏览器都扩展到window层面,和事件目标层面
2)处于目标阶段:该阶段主要执行绑定事件,事件目标在捕获和冒泡阶段都可以触发
3)事件冒泡阶段:该阶段主要将事件目标绑定的结果返回给浏览器:button -> body -> html -> document -> window
二、事件处理程序(事件模型)
根据种类不同,一般分为五种:HTML事件处理程序、DOM0级事件处理程序、DOM1级事件处理、IE事件处理、跨浏览器事件处理
1、HTML事件处理程序
简单来说就是在HTML标签中镶嵌JS代码进行响应的事件处理,具体操作如下
该方式的缺点:
1)时差问题,如下图所示,会报错: Uncaught ReferenceError: fun is not defined
原因:onload 事件会在页面或图像加载完成后立即发生,所以在HTML页面加载时事件fun还没有被定义。
2)作用域链在不同的浏览器中有差异
3)HTML代码和JS代码严重耦合,由此产生DOM0级事件处理
2、DOM 0级事件处理程序
3、DOM2级事件处理程序
事件绑定方法:addEventListener(事件名称,事件处理函数程序,useCapture),useCapture:true捕获阶段执行,默认为false,冒泡阶段执行
事件移除方法:removeEventListener(event, function, useCapture)
4、IE事件处理程序
事件绑定方法:attachEvent(要处理的事件名、作为事件处理程序的函数):
移除事件方法:detachEvent(要处理的事件名、作为事件处理程序的函数)
注意:
1)由于IE8及其更早版本只支持事件冒泡,所以通过attachEvent()添加的事件处理程序都会被添加到冒泡阶段。
2)与DOM 0级的区别:IE事件处理程序会在全局作用域中运行,所以this为window,DOM 0级事件处理程序会在所属元素的作用域中运行。
3)与DOM2级的区别:addEventListener事件名称不需要加‘on’,attachEvent需要;
addEventListener绑定多个相同事件会按照绑定的顺序触发,而attachEvent按照绑定的相反顺序触发。
5、跨浏览器事件处理程序
由程序员自己封装的一些方法,可以在大多数浏览器中使用,解决其兼容问题,所以只需要关注冒泡阶段即可
(注:上图是https://www.jb51.net/article/144562.htm该网站中封装的一个方法,由于学习中还没有这个要求故没有实践,我自己封装后会进行替换)
三、事件委托
将子元素的事件绑定给父元素就是事件的委托。
使用场景:例如如下图,给所有的超链接绑定一个单击事件,如果给li元素绑定,那么新增li元素则没有该事件,这就需要使用事件委托