事件
JS与HTML之间的交互通过事件实现。
事件就是文档或浏览器窗口中发生的一些特定的交互瞬间。
可以使用监听器来预定事件,以便事件发生时执行相应的代码。这种在传统软件工程中被称为观察者模式
事件流
事件流描述的是从页面中接受事件的顺序
事件冒泡
微软提出了名为事件冒泡的事件流。
事件从目标元素开始执行,一层一层往上执行,直到最顶层的元素
事件捕获
网景提出另一种事件流名为事件捕获。
事件从最顶层元素开始执行,一层一层往下执行,直到目标元素。
标准的浏览器事件流是 事件捕获流
DOM事件模型
DOM事件模型分为捕获和冒泡。一个事件发生之后,会在子元素和父元素之间传播,这种传播分成三个阶段:
第一阶段:从window对象传导到目标节点(从外到内),称之为"捕获阶段";
第二阶段: 在目标节点上触发,称之为"目标阶段";
第三阶段: 从目标节点传回window对象(从内到外),称之为"冒泡阶段";
DOM级别与DOM事件
DOM级别一共可以分为四个级别:DOM 0级(通常把DOM1规范形成之前的叫做DOM 0级)、DOM 1级、DOM 2级、DOM 3级。
DOM事件分为三个级别:DOM 0级事件处理,DOM 2级事件处理、DOM 3级事件处理
DOM 1级标准没有相关事件内容,所以没有DOM 1级事件
HTML事件处理程序
最早的事件处理方式是HTML事件处理程序,也是最早的事件处理方式。
直接在HTML代码里面定义了一个 onclick属性触发事件
缺点:HTML和JavaScript代码紧密耦合,如果我们需要修改函数名,HTML代码和javaScript代码都需要改动。
优点:不需要操作DOM就可以完成事件绑定
DOM 0级事件
DOM 0级事件绑定,在javaScript代码中指定对象,将一个函数赋值给一个事件处理属性。
规避了HTML事件中HTML代码和javaScript代码耦合的问题,而且可以通过给事件处理属性赋值null来解绑事件。
缺点:
- 不能给一个元素同时添加多个事件。
- 不能控制元素的事件流,当前元素事件在冒泡阶段执行
DOM 2级事件
DOM 2级事件定义了addEventListener和removeEventListener两个方法,分别用来绑定和解绑事件方法中包含三个参数:
- event-name: 事件名称,可以是标准的DOM事件
- callback: 回调函数,当事件触发时,函数会被注入一个参数为当前的事件对象 event
- useCapture:是否在捕获时候执行事件处理函数,默认是false。
IE8级以下版本不支持addEventListener和removeEventListener,需要使用attachEvent(‘onclick’, showFn)绑定事件和detachEvent(‘onclick’, showFn) 解绑事件, IE8以下版本只支持冒泡型事件。
DOM 3级事件
DOM3级事件是在DOM2级事件的基础上添加很多事件类型。
UI事件,当用户与页面上的元素交互时触发,如:load、scroll
焦点事件,当元素获得或失去焦点时触发,如:blur、focus
鼠标事件,当用户通过鼠标在页面执行操作时触发如:dbclick、mouseup
滚轮事件,当使用鼠标滚轮或类似设备时触发,如:mousewheel
文本事件,当在文档中输入文本时触发,如:textInput
键盘事件,当用户通过键盘在页面上执行操作时触发,如:keydown、keypress
合成事件,当为IME(输入法编辑器)输入字符时触发,如:compositionstart
变动事件,当底层DOM结构发生变化时触发,如:DOMsubtreeModified
同时DOM3级事件也允许使用者自定义一些事件。
事件委托
事件委托还有一个名字叫事件代理,javaScript高级程序设计上讲:事件委托就是利用事件冒泡,指定一个事件处理程序,就可以管理某一类型的所有事件。
优点:
- 减少内存消耗,提高性能。
如果给每个列表项一一都绑定一个函数,那对于内存消耗是非常大的,效率上需要消耗很多性能。借助事件代理,我们只需要给父容器绑定方法即可, - 动态绑定事件
在很多时候,我们需要通过用户操作动态的增删列表项元素,如果一开始给每个子元素绑定事件,那么在列表发生变化时,就需要重新给新增的元素绑定事件,如果用事件代理就会省去很多这样麻烦。
Event对象常见的应用
1. event. preventDefault()
如果调用这个方法,默认事件行为将不再触发
2. event.stopPropagation()
方法阻止事件冒泡到父元素
3. stopImmediatePropagation() 方法阻止监听同一事件的其他事件监听器被调用。
如果多个事件监听器被附加到相同元素的相同事件类型上,当此事件触发时,它们会按其被添加的顺序被调用。如果在其中一个事件监听器中执行 stopImmediatePropagation() ,那么剩下的事件监听器都不会被调用。
4. Event.target
触发事件的对象 (某个 DOM 元素) 的引用
5. Event.currentTarget
标识是当事件沿着 DOM 触发时事件的当前目标。它总是指向事件绑定的元素,而 Event.target 则是事件触发的元素。
改变冒泡捕获的顺序
在 DOM 标准事件模型中,是先捕获后冒泡。但是如果要实现先冒泡后捕获的效果,对 于同一个事件,监听捕获和冒泡,分别对应相应的处理函数,监听到捕获事件,先暂 缓执行,直到冒泡事件被捕获后再执行捕获之间。
参考文档
https://zhuanlan.zhihu.com/p/171760778
https://www.jianshu.com/p/622d994906f7
https://segmentfault.com/a/1190000017259386