songbensong songbensong
首页
  • 学习笔记

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《ES6 教程》
    • 《Vue》
    • 《React》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • TypeScript
    • JS设计模式总结
HTML/CSS
JavaScript
计算机网络
操作系统
更多
  • 分类
  • 标签
GitHub (opens new window)

松本松

一直在路上
首页
  • 学习笔记

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《ES6 教程》
    • 《Vue》
    • 《React》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • TypeScript
    • JS设计模式总结
HTML/CSS
JavaScript
计算机网络
操作系统
更多
  • 分类
  • 标签
GitHub (opens new window)
  • HTML

    • 页面HTML-知识点
    • 什么是BFC
    • defer与async属性
    • 常用meta整理
    • 小程序渲染原理
    • DOM事件流 && DOM0 - DOM3 事件模型 && DOM事件流应用场景(冒泡、事件委托)
    • CSS

    • 页面
    • HTML
    simonzhangs
    2022-09-18
    目录

    DOM事件流 && DOM0 - DOM3 事件模型 && DOM事件流应用场景(冒泡、事件委托)

    DOM 元素是 JS 交互的基础,当点击 DOM 元素交互时,捕获事件的过程,并做出对应 JS 操作,因此理解事件流向是很重要的。

    # 一、DOM 事件流

    W3C 标准中规定了事件模型中,一次事件发生的三个过程:

    • 事件捕获:DOM 树节点中,从外向内找监听函数;
    • 事件目标: 找到对应 DOM 节点,有监听函数就调用,并提供对应事件信息(e.target) ,没有的话就跳过;
    • 事件冒泡:从内向外查找监听函数

    # 二、DOM 事件处理方式

    除了 DOM 事件流的标准外,DOM 标准还包括 DOM 的事件模型:DOM0、DOM2、DOM3。它们分别规定了事件的处理阶段:捕获阶段还是冒泡阶段,还规定了怎么添加事件处理函数及个数等等。

    # DOM0 事件

    直接在标签中绑定 onclick 事件;或者在 js 中,获取 DOM 元素,再绑定 onclick = function(){}函数。

    两者区别:标签直接绑定多个事件时,都会触发;而 js 绑定是,后面绑定事件会覆盖前面的。 共同点:事件监听都是在事件冒泡阶段。

    # DOM2 事件

    通过 addEventListener 和 removeEventListener 两个方法添加和移除事件。常用的有两个参数,实际上接收三个参数:

    1. 第一个是事件名(click)
    2. 第二个是事件处理函数
    3. 第三个 boolean 值,true 表示在事件在捕获阶段调用,false 为在冒泡阶段调用,默认值为 false。

    特点:

    • addEventListener 可以为元素添加多个事件处理函数,触发时会按照顺序依次调用;
    • removeEventListener 不能移除匿名添加的函数。

    # DOM3 事件

    DOM3 事件是在 DOM2 事件基础上增加了事件类型:

    • UI 事件,当用户与页面上的元素交互时触发,如:load、scroll
    • 焦点事件,当元素获得或失去焦点时触发,如:blur、focus
    • 鼠标事件,当用户通过鼠标在页面执行操作时触发如:dbclick、mouseup
    • 滚轮事件,当使用鼠标滚轮或类似设备时触发,如:mousewheel
    • 文本事件,当在文档中输入文本时触发,如:textInput
    • 键盘事件,当用户通过键盘在页面上执行操作时触发,如:keydown、keypress
    • 合成事件,当为 IME(输入法编辑器)输入字符时触发,如:compositionstart
    • 变动事件,当底层 DOM 结构发生变化时触发,如:DOMsubtreeModified

    # 三、DOM 事件流应用场景

    # 事件冒泡

    我们常说的事件冒泡,就是 DOM 事件流中的第三阶段。在冒泡阶段,如果监听到有对应函数,就会调用函数执行。常用的事件处理模型也默认的是执行冒泡阶段函数。

    常见应用场景:整个红包券位信息,包含很多子节点信息,如果想要实现点击整个券位都可以跳转,同时实现点击信息上报,则可以将点击事件监听绑定在父节点上,通过 target(点击元素)和 currentTarget(监听元素)来区分实际点击券位。

    当然,某些封装好的独立组件需要避免时间冒泡,可通过 e.stopPropagation()来取消冒泡(实际上取消的并不仅仅只是冒泡,它是阻止整个事件流的传递)。

    提示

    说到 e.stopPropagation(),还得和 e.preventDefault()区别区别。前者阻止的是事件传递,而后者阻止的是默认行为。元素 + 动作 = 默认行为,默认行为参考:https://web.dev/eventing-deepdive/#eventpreventdefault

    # a trick - 这些代码让你的整个网页不可用

    function preventEverything(e) {
      e.preventDefault();
      e.stopPropagation();
      e.stopImmediatePropagation();
    }
    
    document.addEventListener("click", preventEverything, true);
    document.addEventListener("keydown", preventEverything, true);
    document.addEventListener("mousedown", preventEverything, true);
    document.addEventListener("contextmenu", preventEverything, true);
    document.addEventListener("mousewheel", preventEverything, {
      capture: true,
      passive: false,
    });
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

    原理是把网页所有的事件都阻止传递,并且阻止了默认行为,表现:不能滚动、点击跳转、输入......

    # 事件委托

    目的:页面事件处理函数个数会影响页面整体性能,如果添加过多事件处理函数在子 DOM 节点上,会占用过多内存,影响页面性能,委托给父节点来处理就可以了。

    原理:事件委托利用冒泡原理,把事件加到父元素或者更高以及元素身上,从而触发执行效果。


    Codepen:实践出真知 (opens new window)

    参考链接:

    • JavaScript eventing deep dive (opens new window)
    • 什么是 DOM0,DOM2,DOM3? (opens new window)
    • 到底什么是 DOM0、DOM2、DOM3 (opens new window)
    • DOM 事件与事件委托(初理解) (opens new window)
    编辑 (opens new window)
    上次更新: 2022/09/18, 20:29:50
    小程序渲染原理
    CSS教程和技巧收藏

    ← 小程序渲染原理 CSS教程和技巧收藏→

    最近更新
    01
    必备书单
    09-11
    02
    url全过程
    09-10
    03
    异步代码输出顺序
    09-10
    更多文章>
    Theme by Vdoing | Copyright © 2022-2022 simonzhangs | MIT License
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式