DOM事件

693 阅读2分钟

1. 基本概念:DOM事件的级别

2. DOM事件模型

捕获

冒泡

3. DOM事件流

分为三阶段:

  1. 捕获
  2. 事件通过捕获到达目标元素
  3. 从目标元素再上传到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); // 触发自定义事件