1. 基本概念:DOM事件的级别
2. DOM事件模型
捕获冒泡
3. DOM事件流
分为三阶段:
- 捕获
- 事件通过捕获到达目标元素
- 从目标元素再上传到window对象
4. 描述DOM事件捕获(从上到下)的具体流程
<div id="capture">capture</div>
window.addEventListener('click', function () {
console.log('window capture')
}, true)
// trur 表明这个事件是在捕获阶段触发
// 默认值为false,表明实在冒泡阶段触发
document.addEventListener('click', function () {
console.log('document capture')
}, true)
document.documentElement.addEventListener('click', function () {
console.log('html capture')
}, true)
document.body.addEventListener('click', function () {
console.log('body capture')
}, true)
document.getElementById('capture').addEventListener('click', function () {
console.log('ev capture')
}, true)
5. Event对象常见应用
5.1 preventDefault():阻止默认事件
<a href="https://www.zhihu.com/hot" onclick="def(event)">跳转</a>
function def(e) {
e.preventDefault();
<!--阻止a标签的默认事件跳转-->
}
5.2 stopPropagation():阻止冒泡事件
<!--当父级元素和子元素都有事件,使用stopPropagation(),点击子元素使父元素的事件不生效-->
<div class="out" onclick="out(event)"><button onclick="btn(event)">里面</button></div>
function out(e) {
console.log('点击out')
}
function btn(e) {
e.stopPropagation();
console.log('点击按钮')
}
5.3 event.stopImmediatePropagation()
一个按钮绑定了两个click事件,1和2,我想通过优先的方式,比如说,第一个响应函数是A,第2个响应函数是B,依次注册A,B两个事件,我想在A被点击的时候不要再点击B,那么在A的响应函数中加入
event.stopImmediatePropagation()则能阻止B被执行
5.4 event.currentTarget()
event.currentTarget( ) 会返回当前触发事件的元素
<div id="current-target">
<div class="outer" onclick="outer(event)">最外层
<div class="middle" onclick="middle(event)">中间
<div class="inner" onclick="inner(event)">最内层点击我(^_^)</div>
</div>
</div>
// currentTarget 返回的是当前触发事件的元素,包括冒泡和捕获事件
function inner(e) {
console.log('触发了inner 事件' + " currentTarget:" + e.currentTarget.className)
}
function middle(e) {
console.log('触发了middle事件' + " currentTarget:" + e.currentTarget.className)
}
function outer(e) {
console.log('触发了outer事件' + " currentTarget:" + e.currentTarget.className)
}
5.5 event.target()
event.target( ) 会返回触发事件触发的源头元素
<div class="outer" onclick="outer(event)">最外层
<div class="middle" onclick="middle(event)">中间
<div class="inner" onclick="inner(event)">最内层点击我(^_^)</div>
</div>
</div>
// currentTarget 返回的是当前触发事件的元素,包括冒泡和捕获事件
function inner(e) {
console.log('触发了inner 事件' + " currentTarget:" + e.currentTarget.className)
}
function middle(e) {
console.log('触发了middle事件' + " currentTarget:" + e.currentTarget.className)
}
function outer(e) {
console.log('触发了outer事件' + " currentTarget:" + e.currentTarget.className)
}
用法:可以用来监听触发事件的元素是否事件发生的源头元素。这个源头元素指的是,当我点击子元素,虽然父元素的点击事件也会被触发(冒泡机制),但子元素才是事件的源头元素。
6. 自定义事件(或 模拟事件)
<div id="ev">自定义事件</div>
let eve = new Event('custome'); //注册自定义事件
let ev = document.getElementById("id");
ev.addEventListener('custome', function () {
console.log('自定义事件')
})
ev.dispatchEvent(eve); // 触发自定义事件