DOM是什么
操作文档 HTML 的 JS 处理方式为 DOM 即 Document Object Model 文档对象模型。如果对 HTML 很了解使用 DOM 并不复杂。
DOM怎么产生
- 普通文档(.txt)和 HTML/XML文档(.html/*.xml)的区别仅仅是因为后者是有组织的结构化文件;
- 浏览器将结构化的文档以树的数据结构读入浏览器内存,并将每个树的子节点定义为一个NODE(想象这颗树,从根节点到叶子节点都被建模为一个NODE对象); 这每个节点(NODE)都有自己的属性(名称、类型、内容...); NODE之间有层级关系(parents、child、sibling...);
- 以上已经完成文档的建模工作(将文档内容以树形结构写入内存),此时再编写一些方法来操作节点(属性和位置信息),即为NODE API。
-->抽象一下:
DOM是一种将HTML/XML文档组织成对象模型的建模过程; DOM建模重点在于如何解析HTML/XML文档和开放符合DOM接口规范的节点操作API接口。
-->再抽象一下: 解析文档,建模成对象模型,开放API接口。
-->最后: 浏览器在加载页面是会生成 DOM 对象,以供我们使用 JS 控制页面元素。
DOM常用API有什么?
获取节点
1、getElement...(动态)
通过 getElementsByTagname 等 getElementsBy... 函数获取的 Nodelist 与 HTMLCollection 集合是的,即有元素添加或移动操作将实时反映最新状态。
动态特性
通过按钮动态添加元素后,获取的元素集合是动态的,而不是上次获取的固定快照。
2、querySelectorAll(静态)
document.querySelectorAll 获取的集合是静态的,比如
<h1>houdunren.com</h1>
<h1>houdunwang.com</h1>
<button id="add">添加元素</button>
<script>
let elements = document.querySelectorAll('h1')
console.log(elements.length)
let button = document.querySelector('#add')
button.addEventListener('click', () => {
document.querySelector('body').insertAdjacentHTML('beforeend', '<h1>向军大叔</h1>')
console.log(elements.length)
})
</script>
页面添加多一个h1,但是elements不会动态更新。
遍历节点
forOf
Nodelist 与 HTMLCollection 是类数组的可迭代对象所以可以使用 for...of 进行遍历
<div id="houdunren">houdunren.com</div>
<div name="houdunwang">houdunwang.com</div>
<script>
const nodes = document.getElementsByTagName('div')
for (const item of nodes) {
console.log(item)
}
</script>
forEach
Nodelist 节点列表也可以使用 forEach 来进行遍历,但 HTMLCollection 则不可以\
补充:Nodelist 节点列表是什么?
(如使用 getElementsByClassName() 方法,某些(老的)浏览器会返回 NodeList 对象而不是 HTMLCollection。
大多数浏览器会为 querySelectorAll() 方法返回 NodeList 对象。)
借用 Array 的原型 map 方法
节点集合对象原型中不存在 map 方法,但可以借用 Array 的原型 map 方法实现遍历
<div id="houdunren">houdunren.com</div>
<div name="houdunwang">houdunwang.com</div>
<script>
const nodes = document.querySelectorAll('div')
Array.prototype.map.call(nodes, (node, index) => {
console.log(node, index)
})
</script>
当然也可以使用以下方式操作
;[].filter.call(nodes, node => {
console.log(node)
})
借用Array.from
Array.from 用于将类数组转为组件,并提供第二个迭代函数。所以可以借用 Array.from 实现遍历
<div id="houdunren">houdunren.com</div>
<div name="houdunwang">houdunwang.com</div>
<script>
const nodes = document.getElementsByTagName('div')
Array.from(nodes, (node, index) => {
console.log(node, index)
})
</script>
展开语法
下面使用点语法转换节点为数组
<h1>houdunren.com</h1>
<h1>houdunwang.com</h1>
<script>
let elements = document.getElementsByTagName('h1')
console.log(elements)
;[...elements].map((item) => {
item.addEventListener('click', function () {
this.style.textTransform = 'uppercase'
})
})
</sc