DOM

DOM 是 JavaScript 操作网页的接口,全称为“文档对象模型”(Document Object Model)。它的作用是将文档解析成一个由节点和对象(包括元素,属性,文本等)组成的树状结构,通过这个树状结构,可以更方便的访问、修改文档的内容和结构 。

常见的 DOM 节点类型:

  1. 元素节点(Element Node):表示 HTML 或 XML 文档中的元素,例如 <div>, <p>, <ul> 等。元素节点是 DOM 树的主要组成部分。

  2. 属性节点(Attribute Node):表示元素节点的属性,例如 classidsrc 等。属性节点是元素节点的子节点。

  3. 文本节点(Text Node):表示元素节点的文本内容,例如元素中的纯文本内容或内部的文本节点。文本节点是元素节点的子节点。

  4. 注释节点(Comment Node):表示 HTML 或 XML 文档中的注释,例如 <!-- 这是一个注释 -->。注释节点也是元素节点的子节点。

Dom事件类

DOM事件的级别

DOM事件类
事件级别

DOM0

element.onclick=function(){}

DOM2

element.addEventListener('click', function(){} ,false)

DOM3

element.addEventListener('keyup', function(){} , false)

  • 当第三个参数为 false 时,表示事件处理程序在冒泡阶段执行。冒泡是指事件从最具体的元素开始,然后逐级向上传播到最不具体的元素。这是事件处理程序的默认行为,如果不指定参数,默认为 false

  • 当第三个参数为 true 时,表示事件处理程序在捕获阶段执行。捕获是指事件从最不具体的元素开始,然后逐级向下传播到最具体的元素。在捕获阶段执行事件处理程序通常用得较少。

DOM事件模型

分为捕获(从上到下)和冒泡(从⽬标元素往上)

什么是事件流

事件流,描述的是页面中接受事件的顺序。

事件冒泡

总结来说就是: 当一个元素接收到事件的时候 会把他接收到的事件传给自己的父级,一直到window。

阻止冒泡

1、JS阻止事件冒泡

我们用 e.stopPropagation() 这个方法添加到某事件函数里的末尾,就可以做到阻止冒泡事件。但是IE8及以下不支持e.stopPropagation() 方法,所以就封装一个方法。

<script>
    function stopPropagation(e) {
        e = e || window.event;
        if(e.stopPropagation) {
            e.stopPropagation(); //W3C阻止冒泡方法
        } else {
            e.cancelBubble = true; //IE阻止冒泡方法
        }
    }
</script>

child(区域①)的点击事件函数最后添加 stopPropagation(e) 方法。

<script>
    child.onclick = function (e) {
        alert("你点击了child区域");
        stopPropagation(e);
    };
</script>

复制

  • 再次点击区域①的时候就只弹出 你点击了child区域 这一个弹框。

2、JQ阻止事件冒泡

jq阻止事件冒泡就简单了,直接在事件函数里面添加 return false; 就行了。

<script>
    $("#parents").click(function () {
       alert("你点击了parents区域")
    });
    $("#child").click(function () {
        alert("你点击了child区域");
        return false;
    });
</script>

事件捕获

讲事件捕获之前先了解下addEventListener()方法:

addEventListener()定义与用法

  • document.addEventListener() 方法用于向文档添加事件句柄。

  • 提示: 可以使用 document.removeEventListener() 方法来移除 addEventListener() 方法添加的 事件句柄。

  • 提示:使用 element.addEventListener() 方法为指定元素添加事件句柄。

语法:

document.addEventListener(event, function, useCapture);

复制

参数值:

参数

描述

event

必需。描述事件名称的字符串。 注意: 不要使用 “on” 前缀。例如,使用 “click” 来取代 “onclick”。 提示: 所有 HTML DOM 事件,可以查看我们完整的 HTML DOM Event 对象参考手册。

function

必需。描述了事件触发后执行的函数。 当事件触发时,事件对象会作为第一个参数传入函数。事件对象的类型取决于特定的事件。例如, “click” 事件属于 MouseEvent(鼠标事件) 对象。

useCapture

可选。布尔值,指定事件是否在捕获或冒泡阶段执行。 可能值: true - 事件句柄在捕获阶段执行 false - 默认。事件句柄在冒泡阶段执行

从上面的表格中,可以看到参数值useCapture,为true的时候,事件在捕获过程中就会执行。 用代码感受下:

<div class="div1" id="div1">
    <div class="div2" id="div2"></div>
</div>

<script>
    var div1 = document.getElementById("div1");
    var div2 = document.getElementById("div2");
    
    div1.addEventListener("click",function () {
        alert("你点击了div1")
    },false);  //false 在冒泡阶段执行

    div2.addEventListener("click",function () {
        alert("你点击了div2")
    },false);
</script>
//当点击子元素 div2 的时候,会先弹出 你点击了div2 的弹框后,再弹出 你点击了div1 的弹框。

将bool值改成true时

<div class="div1" id="div1">
    <div class="div2" id="div2"></div>
</div>

<script>
    var div1 = document.getElementById("div1");
    var div2 = document.getElementById("div2");
    
    div1.addEventListener("click",function () {
        alert("你点击了div1")
    },true);  //false 在捕获阶段执行

    div2.addEventListener("click",function () {
        alert("你点击了div2")
    },false);
</script>

//当点击子元素 div2 的时候,会先弹出 你点击了div1 的弹框后,再弹出 你点击了div2 的弹框。,和之前的顺序就不一样了。

描述DOM事件捕获的具体流程

image.png

Event对象的常见应用

image.png

虚拟DOM

虚拟 DOM(Virtual DOM)是一种用于优化前端性能的编程概念,通常与框架如 React 一起使用。它是在内存中对真实 DOM 的一种抽象表示。

在传统的前端开发中,当数据发生变化时,直接操作真实 DOM 可能会引起昂贵的重新渲染和重排操作,导致性能下降。为了解决这个问题,引入了虚拟 DOM 的概念。

虚拟 DOM 的基本思想是,使用一个轻量级的 JavaScript 对象表示真实 DOM 树的结构。当数据发生变化时,首先在虚拟 DOM 中进行操作,然后通过比较虚拟 DOM 和之前的虚拟 DOM 的差异,计算出最小的变化,并将这些变化批量应用到真实 DOM 上。这样可以极大地减少实际的 DOM 操作,从而提高性能。

虚拟 DOM 的基本工作流如下:

  1. 初始化: 初始渲染时,将真实 DOM 结构映射为虚拟 DOM。

  2. 状态变化: 当应用状态发生变化时,生成新的虚拟 DOM。

  3. 虚拟 DOM 比较: 将新生成的虚拟 DOM 与先前的虚拟 DOM 进行比较,找出两者的差异。

  4. 差异应用: 仅将差异部分应用到真实 DOM 上,而非重新渲染整个 DOM。

虽然虚拟 DOM 增加了一些开销,但通过批量处理变化,它通常比直接操作真实 DOM 更高效,尤其在大规模和复杂的应用中。React 是一个使用虚拟 DOM 的典型例子,其 diff 算法可以高效地找出变化,最小化对真实 DOM 的操作。其他框架,如 Vue.js,也采用了类似的机制。

Mutation Observer

当DOM发生改变时会触发Mutation事件,当所有DOM操作结束后,Mutation才会触发(异步触发)

Last updated