一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第19天,点击查看活动详情。
什么是DOM
文档对象模型 (DOM) 是 HTML 和 XML 文档的编程接口
它提供了对文档的结构化的表述,并定义了一种方式可以使从程序中对该结构进行访问,从而改变文档的结构,样式和内容
任何 HTML或XML文档都可以用 DOM表示为一个由节点构成的层级结构
节点分很多类型,每种类型对应着文档中不同的信息和(或)标记,也都有自己不同的特性、数据和方法
<div id="box">
<h1>DOM Document</h1>
<p title="title">content</p>
</div>
这段结构里面,div、p就是元素节点,content就是文本节点,title就是属性节点
DOM操作
日常前端开发,我们都离不开DOM操作
在以前,我们使用Jquery,zepto等库来操作DOM,之后在vue,Angular,React等框架出现后,我们通过操作数据来控制DOM(绝大多数时候),越来越少的去直接操作DOM
但这并不代表原生操作不重要。相反,DOM操作才能有助于我们理解框架深层的内容
下面就来分析DOM常见的操作,主要分为:
- 创建节点 createElement
创建新元素,接受一个参数,即要创建元素的标签名
document.createElement('div') //这里在document下创建一个div元素
createTextNode
创建一个文本节点
const textEl = document.createTextNode("content");
createDocumentFragment
用来创建一个文档碎片,它表示一种轻量级的文档,主要是用来存储临时节点,然后把文档碎片的内容一次性添加到DOM中
const fragment = document.createDocumentFragment();
注意点: 当请求把一个DocumentFragment 节点插入文档树时,插入的不是 DocumentFragment自身,而是它的所有子孙节点
createAttribute
const dataAttribute = document.createAttribute('custom');
consle.log(dataAttribute);
创建属性节点,可以是自定义属性
- 获取节点 querySelector
传入任何有效的css 选择器,即可选中单个 DOM元素(首个),如果页面上没有指定的元素时,返回 null
document.querySelector('.element') // 类选择器
document.querySelector('#element') // ID选择器
document.querySelector('div') // 标签选择器
document.querySelector('[name="username"]') // 属性选择器
document.querySelector('div + p > span') // 后代选择器
querySelectorAll
返回一个包含节点子树内所有与之相匹配的Element节点列表[数组],如果没有相匹配的,则返回一个空节点列表
const notLive = document.querySelectorAll("p");
获取DOM元素的方法还有如下,但一般常用的就是上面两个
document.getElementById('id属性值');返回拥有指定id的对象的引用
document.getElementsByClassName('class属性值');返回拥有指定class的对象集合
document.getElementsByTagName('标签名');返回拥有指定标签名的对象集合
document.getElementsByName('name属性值'); 返回拥有指定名称的对象结合
document/element.querySelector('CSS选择器'); 仅返回第一个匹配的元素
document/element.querySelectorAll('CSS选择器'); 返回所有匹配的元素
document.documentElement; 获取页面中的HTML标签
document.body; 获取页面中的BODY标签
document.all['']; 获取页面中的所有元素节点的对象集合型
- 更新节点 innerHTML
不但可以修改一个DOM节点的文本内容,还可以直接通过HTML片段修改DOM节点内部的子树
// 获取<p id="p">...</p >
var p = document.getElementById('p');
// 设置文本为abc:
p.innerHTML = 'ABC'; // <p id="p">ABC</p >
// 设置HTML:
p.innerHTML = 'ABC <span style="color:red">RED</span> XYZ';
// <p>...</p >的内部结构已修改
innerText、textContent
只能够设置文本内容,不能修改HTML结构
var p = document.getElementById('p-id');
// 设置文本:
p.innerText = '<script>alert("Hi")</script>';
// HTML被自动编码,无法设置一个<script>节点:
// <p id="p-id"><script>alert("Hi")</script></p >
它俩区别在于读取属性时,innerText不返回隐藏元素的文本,而textContent返回所有文本
style
DOM节点的style属性对应所有的CSS,可以直接获取或设置。遇到-需要转化为驼峰命名
const p = document.getElementById('p-id');
// 设置CSS:
p.style.color = '#ff0000';
p.style.fontSize = '20px'; // 驼峰命名
p.style.paddingTop = '20px';
- 添加节点
innerHTML也算添加了节点
如果这个DOM节点是空的,例如,
<div></div>,那么,直接使用innerHTML = '<span>child</span>'就可以修改DOM节点的内容,相当于添加了新的DOM节点。如果这个DOM节点不是空的,那就不能这么做,因为innerHTML会直接替换掉原来的所有子节点
appendChild
把一个子节点添加到父节点的最后一个子节点
<p id="p">JavaScript</p >
<div id="list">
<p id="java">Java</p >
<p id="python">Python</p >
<p id="scheme">Scheme</p >
</div>
<script>
const js = document.getElementById('p')
p.innerHTML = "JavaScript"
const list = document.getElementById('list');
list.appendChild(p); // 把p添加到list最下面
</script>
这里我们是获取DOM元素后再进行添加操作,这个p节点是已经存在当前文档树中,因此这个节点首先会从原先的位置删除,再插入到新的位置
如果动态添加新的节点,则先创建一个新的节点,然后插入到指定的位置
const list = document.getElementById('list'),
const haskell = document.createElement('p');
list.appendChild(haskell)
insertBefore
把子节点插入到指定的位置
parentElement.insertBefore(newElement, referenceElement)
把newElement节点插入到referenceElement之前
setAttribute
在指定元素中添加一个属性节点,如果元素中已有该属性会改变已有属性值
const div = document.getElementById('id')
div.setAttribute('class', 'white');//第一个参数属性名,第二个参数属性值。
-
删除节点 删除一个节点,首先要获得该节点本身以及它的父节点,然后,调用父节点的
removeChild把自己干掉// 获取到需要删除节点: const self = document.getElementById('children'); // 拿到他的父节点: const parent = self.parentElement; // 删除节点 parent.removeChild(self); 注意点:删除后的节点虽然不在文档树中了,但其实它还在内存中,可以随时再次被添加到别的位置