0%

DOM问题汇总

前言

直接操作DOM已经很少在业务场景中用到了,但DOM始终作为前端的基础之一,在面试中往往总能够遇到。本文希望能够汇总以下简单的DOM知识点,让自己在沉迷框架构建时,不至于忽略或者忘记最基础的知识。主要分为两部分:1、常用的DOM方法的汇总;2、DOM的事件机制,主要是事件冒泡与事件捕获。

DOM方法

选取元素

名称选择

名称选择比较简单,主要是根据ID、name属性、标签名称、类名;来选择对应的DOM节点。

1
2
3
4
5
6
7
8
//ID选择器:基于id=""
let id = document.getElementById("id");
//名称选择器:基于name属性
let name = document.getElementsByName("name");
//标签选择器:利用HTML元素的标签名称选取指定类型的元素
var h1 = document.getElementsByTagName("h1");
//类选择器:利用HTML的class属性值选择元素
let title = document.getElementsByClassName(title);

CSS选择

通过CSS样式表选择器的强大语法,也可以来选择元素,返回第一个匹配的元素,或者返回元素数组。

1
2
3
var title = document.querySelector("#title");   // CSS ID选择
var h1 = document.querySelector("h1"); //选取第一个h1元素
var h1s = document.querySelectorAll("h1"); //返回所有h1标签元素

相近节点选取

节点:页面中所有的内容都是节点(标签,属性,文本:文字,空格,换行)文档:document—-页面中的顶级对象元素:页面中所有的标签,标签–元素–对象(通过DOM的方式来获取这个标签,得到了这个对象,此时这个对象叫DOM对象)。

关于节点的选取有如下的方法:

1
2
3
4
5
6
7
8
9
h1.parentNode;//父节点
h1.childNodes;//以数组形式返回子节点
h1.firstChild; h1.lastChild;
h1.nextSibling;//下一个兄弟节点
h1.previousSibling;//前一个兄弟节点
h1.nodeType;
//返回节点类型的数字表示:1-element节点;3-text节点;8-comment节点;9-document节点;11-documentFragment节点
h1.nodeValue;//返回Text 节点 或 Comment 节点的值
h1.nodeName;//返回元素的标签名,以大写形式表示

元素相关的选取同样有如下的方法:

1
2
3
4
h2.children;//以数组的形式返回所有的子元素
h2.firstElementChild; h2.lastElementChild;//返回首子元素与尾子元素
h2.nextElementSibling; h2.previousElementSibling;//返回上一兄弟元素与下一兄弟元素
h2.childElementCount;//返回子元素数量

属性相关

表示HTML文档元素的HTMLElement对象定义了读/写属性,它们对应于元素的HTML属性。 HTMLElement定义的通用HTML属性,包括id、lang、dir、事件处理程序onclick及表单相关属性等。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
h3.getAttribute("width");//返回非标准的HTML属性的值
h3.setAttribute("width", "150px");//设置非标准的HTML属性的值
h3.hasAttribute("height");//判断属性是否存在
h3.removeAttribute("width");//删除某一属性
//在HTML5文档中,任意以 data- 为前缀的小写的属性名字都是合法的。这些 “数据集属性” 定义了一种标准的、附加额外数据的方法
//以data-x = ""为例
h3.dataset.x;
//Node节点定义了 attributes 属性,针对 Element 对象,attributes 是元素所有属性的类数组对象
//索引 attributes 对象得到的值是 Attr 对象。Attr 的 name 和 value 返回该属性的名字和值
let a = h3.attributes.src.value;

h4.innerHTML;//以字符串形式返回这个元素的内容。 也可以用来替换元素当前内容
h4.outerHTML;//以字符串形式返回这个元素及内容。 也可以用来替换元素当前内容
h4.textContent;//查询或替换纯文本元素内容的标准方法是用Node的textContent属性来实现。

创建节点

1
2
3
4
5
6
document.createElement("h1");//使用document 对象的createElement () 方法创建新的Element节点
document.createTextNode("文本节点");//创建纯文本节点
document.createDocumentFragment();//创建文档片段,往往有更好性能
//因为文档片段存在于内存中,并不在Dom树中,所以将子元素插入到文档片段时不会引起页面回流 (对元素位置和几何上计算)
document.createCmoment("....");//创建注释节点
h4.cloneNode(true);//通过复制已存在的节点来创建新的文档节点。传参数true表示深克隆,false表示浅复制

插入、修改节点

1
2
3
4
5
6
7
8
h5.appendChild("h1");//在指定元素上插入子节点,并使其成为该节点的最后一个子节点
//一般先新建子节点,再插入子节点
h5.insertBefore("h1", "h2");
//1. 在父节点上调用本方法2. 第一参数表示待插入的节点
//3. 第二参数是父节点中已经存在的子节点,新节点插入到该节点的前面
h5.removeChild("h2");//在父节点中调用,参数是待删除的节点
h5.replaceChild("h2,", "h2");
//1. 在父节点上调用;2. 第一参数是新节点;3. 第二个参数是需要替换的节点

DOM事件机制

1、事件是在编程时系统内发生的动作或者发生的事情

2、事件是要绑定在元素上的。比如给一个div元素绑定一个鼠标悬浮事件,给一个ol元素绑定鼠标单击事件。

3、可以使用事件监听函数(也叫事件处理程序、侦听器)来监听事件,以便事件发生时执行相应的代码

事件发生时元素节点之间按照特定的顺序传播,这个过程即DOM事件流,描述的是从页面接收事件的顺序。

冒泡与捕获

首先开始事件捕获阶段:从DOM树最根部的节点window开始,沿着DOM树向下遍历每个元素,直到触发元素目标元素target。如果这些元素也注册了click事件(且为捕获阶段),就会执行他们相应的事件监听函数。即从上到下触发父元素对应的事件。在事件捕获这一阶段,为截获事件提供了机会。

当前目标阶段:实际的目标接收到,并执行对应得事件监听函数。

事件冒泡阶段:从触发元素目标元素target开始,向上逆着遍历DOM树,直到最根部window元素。如果这些元素也注册了click事件(且为冒泡阶段),就会执行他们相应的事件监听函数

我们在使用 addEventListener 监听事件时,addEventListener(‘click’, fn, bool)如果第三个参数 bool 不传,或者传 false, 那么我们会在冒泡阶段调用 fn如果第三个参数 Bool 传值为 true, 那么我们会在捕获阶段调用 fn。因此,默认是在冒泡阶段来监听事件的。

捕获不可以取消,但是冒泡可以取消,e.propagation()就可但是有一些事件不可以取消冒泡,比如 scroll 事件。

1
2
3
4
5
6
<div>
<span>文字</span>
</div>
e.target 用户正在操作的元素
e.currentTarget 程序员在监听的元素
假设我们监听的是 div, 但用户实际点击的是文字,那么e.target 就是 span 标签,e.currentTarget 就是 div 标签。

事件委托

冒泡阶段,浏览器从用户点击的内容从下往上遍历至 window,逐个触发事件处理函数,因此可以监听一个祖先节点(例如爸爸节点、爷爷节点)来同时处理多个子节点的事件。

主要的作用有:1、省掉监听数,节省内存;要监听多个兄弟元素时,不如只监听父元素,并在事件处理函数中,利用e.target来判断到底是哪一个子元素触发了事件,再进行对应的处理即可。

2、监听不存在的元素,即动态元素。

-------------本文结束感谢您的阅读-------------
坚持原创技术分享,您的支持将鼓励我继续创作!