js 为dom绑定事件发生了什么

一、js 为dom绑定事件发生了什么?

  1. DOM2级事件规定事件分为三个阶段
事件捕获阶段事件捕获定义了事件首先由最外层的元素(window)接收,然后才是下级元素
处于目标阶段捕获到当前绑定的dom元素
事件冒泡阶段从当前捕获阶段线上冒泡到document元素

addEventListener 可选参数介绍:

capture: Boolean设置为true时,表示捕获阶段触发事件,设置为false时,冒泡阶段触发事件。 表示 listener 会在该类型的事件捕获阶段传播到该 EventTarget 时触发。
once: Boolean表示 listener 在添加之后最多只调用一次。如果是 true, listener 会在其被调用之后自动移除。
passive: Boolean设置为true时,表示 listener 永远不会调用 preventDefault()。如果 listener 仍然调用了这个函数,客户端将会忽略它并抛出一个控制台警告。

举例证实:冒泡阶段

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>js 为dom绑定事件发生了什么</title>
</head>
<body id="body">
<div id="div">
    <section id="section">
        <button id="button">button</button>
    </section>
</div>
<script>
    /**
     * @methods target.addEventListener(type, listener[, options]);
     * @type 表示监听事件类型的字符串。 浏览器事件参考: https://developer.mozilla.org/zh-CN/docs/Web/Events
     * @options(可选) {capture:Boolean,once:Boolean,passive:Boolean}
     */
    const button = getElId('button');
    const section = getElId('section');
    const div = getElId('div');
    const body = getElId('body');

    button.addEventListener('click', function () {
        console.log(this.id);
    }, { capture: false, once: false, passive: false });

    section.addEventListener('click', function () {
        console.log(this.id);
    }, { capture: false, once: false, passive: false });

    div.addEventListener('click', function () {
        console.log(this.id);
    }, { capture: false, once: false, passive: false });

    body.addEventListener('click', function () {
        console.log(this.id);
    }, { capture: false, once: false, passive: false });
    /**
     * @dec 简单装饰着模式
     * @param el
     * @returns {Element}
     */
    function getElId (el) {
        return document.getElementById(el);
    }
</script>
</body>
</html>

结果:上述执行输出的顺序 验证了冒泡阶段 button->section->div->body
在这里插入图片描述
举例证实:捕获阶段 (capture:true) 即可设置事件在不会阶段执行

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>js 为dom绑定事件发生了什么</title>
</head>
<body id="body">
<div id="div">
    <section id="section">
        <button id="button">button</button>
    </section>
</div>
<script>
    /**
     * @methods target.addEventListener(type, listener[, options]);
     * @type 表示监听事件类型的字符串。 浏览器事件参考: https://developer.mozilla.org/zh-CN/docs/Web/Events
     * @options(可选) {capture:Boolean,once:Boolean,passive:Boolean}
     */
    const button = getElId('button');
    const section = getElId('section');
    const div = getElId('div');
    const body = getElId('body');

    button.addEventListener('click', function () {
        console.log(this.id);
    }, { capture: true, once: false, passive: false });

    section.addEventListener('click', function () {
        console.log(this.id);
    }, { capture: true, once: false, passive: false });

    div.addEventListener('click', function () {
        console.log(this.id);
    }, { capture: true, once: false, passive: false });

    body.addEventListener('click', function () {
        console.log(this.id);
    }, { capture: true, once: false, passive: false });
    /**
     * @dec 简单装饰着模式
     * @param el
     * @returns {Element}
     */
    function getElId (el) {
        return document.getElementById(el);
    }
</script>
</body>
</html>

在这里插入图片描述
结果:上述执行输出的顺序 验证了捕获阶段 body->div->section->button

举例证实:捕获阶段 (once) 即可设置事件只会执行一次,类似于jQuery once

  button.addEventListener('click', function () {
        console.log(this.id);
    }, { capture: true, once: false, passive: false });

结果:虽然当前button事件只是执行一次,但是捕获和冒泡阶段的事件还是正常执行的。
在这里插入图片描述
举例证实:js实现事件委托的方法

    /**
     * @methods target.addEventListener(type, listener[, options]);
     * @type 表示监听事件类型的字符串。 浏览器事件参考: https://developer.mozilla.org/zh-CN/docs/Web/Events
     * @options(可选) {capture:Boolean,once:Boolean,passive:Boolean}
     */
    const body = getElId('body');
    body.addEventListener('click', function (event) {
        if (event.target.nodeName.toLowerCase() === 'button' || event.target.id === 'button') {
            console.log(`将button事件委托给body成功执行`);
        }
    }, { capture: false, once: false, passive: false });
    /**
     * @dec 简单装饰着模式
     * @param el
     * @returns {Element}
     */
    function getElId (el) {
        return document.getElementById(el);
    }

js绑定事件及参数的配置细信息参考:https://developer.mozilla.org/zh-CN/docs/Web/API/EventTarget/addEventListener#%E7%94%A8%E6%B3%95%E8%AF%B4%E6%98%8E

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值