DOM 允许 JavaScript 对 HTML 事件作出反应。JavaScript 能够在事件发生时执行,比如当用户点击某个 HTML 元素时。JavaScript与HTML之间的交互是通过事件实现的,事件就是文档或浏览器窗口中发生的一些特定的交互瞬间。
一个DOM事件一般由三部分组成,事件源、事件类型、事件处理程序:
- 事件源:事件被触发的对象 ,例如,按钮对象
- 事件类型:如何触发?触发什么事件?例如鼠标点击动作,鼠标点击后的抬起动作,键盘按下等
- 事件处理程序:通过一个函数赋值的方式,定义触发事件后执行的动作
执行事件的步骤:
- 获取事件源
- 注册事件(绑定事件)
- 采用函数赋值形式添加事件处理程序
DOM事件模型
<div class="爷爷">
<div class="爸爸">
<div class="儿子">
文本
</div>
</div>
</div>
在这段代码中 .爷爷>.爸爸>.儿子,分别添加事件监听 fnYe / fnBa / fnEr 首先需要明确两个问题
- 点击低级的元素可以视作点击了高级的元素
- W3C在2002年发布了标准, 文件名为DOM Level 2 Events Specification, 规定浏览器同时支持两种调用顺序.首先按爷爷->爸爸->儿子顺序看有没有函数监听, 然后按儿子->爸爸->爷爷顺序看有没有函数监听。
简而言之,onclick为DOM0级,没有DOM1级,addEventListener为DOM2级,在DOM2级基础上实现的复杂操作是DOM3级,具体细节查询MDN。
事件冒泡处理模型(Bubbling)
是IE浏览器使用的事件模型,事件冒泡处理模型,在事件发生时,首先在事件发生的最小范围元素中捕获事件,然后向上传播,直到根节点,在DOM树上就是事件从叶子节点传播到根节点。在本文代码中表现为爷爷->爸爸->儿子的顺序
事件捕获处理模型(Captrue)
事件捕获处理模型更为泛用,事件发生时首先在最顶级的元素上触发,传播到范围最小的最低级的元素上。在DOM树上的表现就是由根节点传播到叶子节点。在本文代码中表现为儿子->爸爸->爷爷的顺序
事件绑定
IE5:baba.attachEvent('onclick', fn) // 冒泡阶段
网景:baba.addEventListener('click', fn) // 捕获阶段
W3C: baba.addEventListener('click', fn, bool)
如果bool为true,就让fn走捕获,即当浏览器在捕获阶段发现baba有fn监听,就会调用fn,并提供事件信息
如果bool不传值或为falsy,就让fn走冒泡,即当浏览器在冒泡阶段发现baba有fn监听函数,就会调用fn,并提供事件信息
target与currentTarget的区别
区别:
e.target - 用户操作的元素
e.currentTarget - 程序员监听的元素
this是e.currentTarget,尽量不要使用 非常容易混淆
举例:
div>span{文字},用户点击文字
e.target就是span
e.currentTarget就是div
只有一个对象的情况
如果在同一个元素中分别在事件捕获和事件冒泡中分别加入了两个事件。
以前:谁先监听谁先执行
2022年后:浏览器修正了这一问题,先捕获后冒泡
事件对象的常见操作方法
阻止默认事件
event. preventDefault()
如果调用这个方法,默认事件行为将不再触发。例如表单一点击提交按钮(submit)跳转页面、a标签默认页面跳转或是锚点定位等。
例如阻止a标签的自动跳转
<a id="test" href="http://www.cnblogs.com">链接</a>
<script>
test.onclick = function(e){
e = e || window.event;
e.preventDefault();
}
</script>
阻止冒泡
e.stopPropagation()可以中断冒泡
- 不可取消冒泡
有的事件不可取消冒泡;比如:搜scroll event MDN,看Bubbles(事件是否冒泡)和Cancelable(开发者是否可以取消冒泡)
例子:如何取消滚动
1.scroll事件是不可取消冒泡,因此阻止scroll默认动作没用
x.addEventListener('scroll', (e)=>{
e.stopPropagation() // 取消冒泡
e.preventDefault() // 阻止默认动作scroll的默认动作不是scroll,是wheel
})
2.阻止wheel滚动的默认动作;
x.addEventListener('wheel',(e)=>{
e.preventDefault()
})
如果是手机,组织touchstart的默认动作
x.addEventListener('touchstart',(e)=>{
e.preventDefault()
})
3.取消滚动条所在的元素(CSS)
::-webkit- scrollbar{
width: 0 !important
}
其他浏览器自带的事件
自定义事件
CustomEvent() 构造函数, 创建一个新的事件对象 CustomEvent。
语法
let myEvent = new CustomEvent(typeArg, eventInit);
参数
typeArg :表示创建事件的名称;
eventInit :可选配置项,包括:
detail表示该事件中需要被传递的数据,在 EventListener 获取。
bubbles表示该事件是否冒泡。
cancelable表示该事件能否被取消。
示例
button1.addEventListener('click', ()=>{
const event = new CustomEvent("frank", {"detail":{name:'frank', age: 18}})
button1.dispatchEvent(event)
})
button1.addEventListener('frank', (e)=>{
console.log('frank')
console.log(e)
})