什么是事件?
事件是 HTML文档
和浏览器窗口
中发生的特定的交互
瞬间,事件就发生了。
常见的有加载事件、鼠标事件、自定义事件等
什么是事件流?
由于 DOM 是一个树结构
,如果在父子节点绑定事件时候,当触发子节点的时候,就存在一个顺序
问题,这就涉及到了事件流的概念
事件流都会经历三个阶段:
事件捕获阶段
(capture phase)事件处理阶段
(target phase)事件冒泡阶段
(bubbling phase)
事件冒泡
(IE提出的事件流)是一种从由内往外
的传播方式,由最具体的元素(触发节点)然后逐级向上传递直到根节点。也就是 DOM 中最高层的父节点。
事件捕获
(网景公司提出的事件流)与事件冒泡相反,由外往内
从事件发生的顶点开始,逐级往下查找,一直到目标元素。(事件最开始由不太具体的节点最早接受事件,而最具体的节点(触发节点)最后接受事件)。
事件模型
事件模型可以分为三种:
- 原始事件模型(DOMO级)
标准事件模型
(DOM2级)- IE事件模型(基本不用)
原始事件模型(只支持冒泡,不支持捕获)
事件绑定监听函数有两种:
- html代码中直接绑定
- 通过js代码绑定
写法:
ini
// html代码中直接绑定
<input type="button" onclick="fun()">
// js代码绑定
var btn = document.getElementById('.btn');
btn.onclick = fun;
// 删除DOM0级事件
btn.onclick = null;
特性:
- 绑定速度快
- 只支持冒泡,不支持捕获
- 同一个类型的事件只能绑定一次(后绑定的会覆盖之前绑定的事件)
- 删除DOM0级事件只需将绑定事件设置为
null
标准事件模型
标准事件模型中,一次事件共有三个过程:
事件捕获阶段
: 事件从 document 一直向下传播到目标元素,依次检查经过的节点是否绑定了事件监听函数,如果有则执行事件处理阶段
: 事件到达目标元素,触发目标元素的监听函数事件冒泡阶段
: 事件从目标元素冒泡到 document,依次检查经过的节点是否绑定了事件监听函 数,如果有则执行
参数如下:
eventType
: 指定事件类型(不要加on)handler
: 是事件处理函数useCapture
: 是一个boolean
用于指定是否在捕获阶段进行处理
,一般设置为false
与IE浏览器保持一致
写法:
scss
// 事件绑定监听函数
addEventListener(eventType, handler, useCapture)
// 事件移除监听函数
removeEventListener(eventType, handler, useCapture)
var btn = document.getElementById('.btn');
btn.addEventListener('click', showMessage, false);
btn.removeEventListener('click', showMessage, false);
特性:
- 可以在一个Dom元素上绑定
多个
事件处理器。 - 执行时机(第三个参数设置为
true
在捕获过程
中执行,反之在冒泡过程中执行处理函数)
event.eventPhase:
- 1 : 捕获阶段
- 2 : 事件执行阶段
- 3 : 事件冒泡阶段
IE事件模型
IE事件模型共有两个过程:
- 事件处理阶段: 事件到达目标元素,触发目标元素的监听函数。
- 事件冒泡阶段: 事件从目标元素冒泡到 document,依次检查经过的节点是否绑定了事件监听函数,如果有则执行
scss
attachEvent(eventType,handler)
detachEvent(eventType,handler)
var btn = document.getElementById('.btn');
btn.attachEvent('onclick',showMessage);
btn.detachEvent('onclick',showMessage);
什么是事件委托 事件委托又名事件代理、应用场景?
什么是事件代理?
事件委托就是利用事件冒泡,就是把子元素
的事件都绑定到父元素
上。如果子元素阻止了事件冒泡,那么委托也就没法实现了
阻止事件冒泡
csharp
// 阻止事件冒泡
event.stopPropagation()
事件代理的优点
减少了事件绑定
,减少了重复操作- 从而
减少内存占用
,提高性能
事件代理的局限性
focus
、blur
这些事件没有事件冒泡机制,所以无法进行委托绑定事件mousemove
、mouseout
这样的事件,虽然有事件冒泡,但是只能不断通过位置去计算定位。对性能消耗高,因此也是不适合于事件委托的
如果把所有事件都用事件代理,可能会出现事件误判,即本不该被触发的事件被绑定上了事件
事件代理的应用场景
- ul li
适合事件委托的事件有:
- click
- mousedown,mouseup
- keydown, keyup, keypress