1,DOM级别
有DOM0~4级,其中dom1级没有定义相关事件就不是标准的dom事件,它似乎是专注于 HTML 和 XML 文档模型
- DOM0级(HTML事件):element.onclick=function(event){}
<button type="button" onclick="hi()"></button>
function hi() {
console.log('Hi World');
}
- 缺点一:一个元素同种类型的事件只能注册一个事件处理程序,多事件会被互相覆盖
- 却大的缺点:HTML和JS耦合太强,如果我们需要修改函数名 就必须修改两个地方
- 优点:是不需要操作DOM来完成事件绑定
- DOM2级:element.addEventListener('click',function(event){},false)冒泡
<button id="btn" type="button"></button>
var btn = document.getElementById('btn');
function hi() {
console.log('hi World');
}
btn.addEventListener('click', hi, false); //没有on
btn.addEventlistener('mouseover',showfn,false) //允许添加多个事件
// btn.removeEventListener('click', hi, false); 解绑事件
- 同一个元素上的同类型事件可以注册多个处理函数。事件触发时按照注册顺序触发。
- 支持捕获和冒泡,当布尔值为ture是捕获,falsy为冒泡()、
- 注意,IE事件处理程序没有第三个参数,因为IE早期版本只支持事件冒泡,所以默认就是事件冒泡。
- DOM3级:element.addEventListener('keyup',function(event){},false),新增的鼠标键盘事件
可以自定义事件 在DOM2级的事件上添加了很多事件类型 UI事件 load,scroll 焦点事件, blur,focus 鼠标事件,dbclick,mouseup ...
2,DOM事件模型和事件流
DOM事件模型分别为捕获和冒泡。一个事件发生后,会在子元素和父元素之间传播。这种传播分成三个阶段。

1,捕获阶段
事件从window对象自上而下向目标节点传播的阶段
addEventListener的第三个参数bool为ture
不可取消,但冒泡可以阻止
2,目标阶段(target):真正的目标节点正在处理事件的阶段
3,冒泡阶段:事件从目标节点自下而上向window对象传播的阶段。
e.stopPropagation()中断冒泡,浏览器不再向上传播// 一般用于封装某些独立的组件
一些不能取消的冒泡事件:Bubbles表示是否冒泡;Cancelable表示是否支持开发者取消冒泡 具体口查看mdn文档,英文版更全
<div class="outter" hiOutter()>
<div class="middle" hiMiddle()>
<div class="inner" hiInner()>
我目标就在此
</div>
</div>
</div>
function hiOutter() {
console.log('hiOutter');
}
function hiMiddle() {
console.log('hiMiddle');
}
function hiInner() {
console.log('hiInne');
}
事件委托
- 定义
事件委托指的是不在事件的发生地(直接DOM)上设置监听函数,而是在其父元素上设置监听函数,通过事件冒泡,父元素可以监听到被触发的子元素事件,通过判断事件发生元素DOM的类型,来作出不同的响应。当子元素有很多时,使用事件委托可以避免对特定的每个节点添加事件监听器,事件监听被添加到它们的父元素上,事件监听函数这是可以从子元素上冒泡上来的事件,找到是哪个子元素事件。
- 事件委托举例
最经典的就是ul和li标签的事件监听,比如我们在添加事件时候,采用事件委托机制,不会在li标签上直接添加,而是在ul父元素上添加。
第一步:给父元素绑定事件。给元素ul添加绑定事件,通过addEventListener为点击事件click添加绑定。
第二步:监听子元素的冒泡事件。这里默认是冒泡,点击子元素li会向上冒泡。
第三步:找到是哪个子元素的事件。 通过匿名回调函数的参数event用来接收事件对象,通过event.target获取触发事件的目标。
- 使用事件委托的好处
- 省内存
- 动态绑定