DOM基本概念
1. Document Object Model(DOM)
- 定义:DOM 是将网页抽象成一个 Document 对象,通过 window.document 可以获取网页节点并进行操作。
2. 事件原理
- onclick 示例:onclick 是元素默认存在的属性,其初始值为 null。绑定 onclick 事件的本质是对 onclick 进行重写,将其设置为一个函数。当事件触发时,该函数的 this 指向调用它的节点元素。
3. 浏览器引擎
- 渲染引擎:负责页面的渲染,不进行 JavaScript 操作。
- JS 引擎:负责执行 JavaScript 代码,不进行页面操作。
4. 跨线程操作
- JavaScript 不能直接对页面进行操作,而是通过 JS 引擎中的 DOM 操作在渲染引擎中引发对应的操作。
- 当 DOM 节点未放入页面时,对 DOM 节点的操作不会引起渲染引擎的重新渲染。
- 操作原生属性时,会自动同步到渲染引擎;操作非原生属性则需要手动同步。
5. property 与 attribute
- property:存在于 JS 引擎中,支持多种数据类型。
- attribute:存在于渲染引擎中,仅支持字符串类型。
6. 元素的概念
- 本质:元素是对象,可以通过 console.dir() 查看其结构。
- 原型链:以 div 标签为例,其原型链为 div 实例 --> HTMLDivElement.prototype --> HTMLElement.prototype --> Element.prototype --> Node --> EventTarget --> Object。
- 元素与节点关系:元素是节点的一种,节点类型包括元素节点(Element)、文本节点(Text)、注释节点(Comment)等。
DOM的API
1. 获取元素
2. 获取特定元素
- html 根标签元素:使用 document.documentElement 可以获取 <html> 根标签元素。
- head 元素:使用 document.head 可以获取 <head> 元素。
- body 元素:使用 document.body 可以获取 <body> 元素。
- 所有元素:使用 document.all 可以返回所有元素的集合,但这是一个伪数组,且在某些情况下可能为 falsy 值。
3. 节点增加操作
- 创建节点:使用 document.createElement('tagName') 可以创建指定标签名的元素节点;使用 document.createTextNode('text') 可以创建文本节点。
- 复制节点:使用 node.cloneNode(true/false) 可以复制节点,true 表示深拷贝,false 表示浅拷贝。
- 插入节点:使用 parentNode.appendChild(childNode) 可以将子节点插入到父节点的末尾;使用 element.innerText 或 element.textContent 可以将字符串内容设置为节点的文本内容。
4. 节点删除操作
- removeChild:使用 parentNode.removeChild(childNode) 可以删除子节点。
- remove:直接使用 node.remove() 可以删除节点。
- 内存管理:将节点从树中删除后,将其变量赋值为 null 可以帮助从内存中删除该节点(虽然现代浏览器的垃圾回收机制通常会自动处理这种情况)。
5. 节点更改操作
- 类名:使用 element.className 可以设置或获取元素的类名;使用 element.classList 可以操作元素的类名列表(如添加、删除类名)。
- 样式:使用 element.style.propertyName 可以设置或获取元素的指定样式。
- 属性:使用 element.setAttribute('attributeName', 'value') 可以设置元素的指定属性;使用 element.getAttribute('attributeName') 可以获取元素的指定属性值。
- innerHTML:使用 element.innerHTML 可以设置或获取元素内部的 HTML 内容。注意,过度使用 innerHTML 可能会影响性能。
6. 节点查询操作
- 基本属性:使用 element.id、element.style、element.className 等可以获取或设置元素的基本属性。
- 父节点与子节点:
使用 element.parentNode 可以获取元素的父节点。
使用 element.childNodes 可以获取元素的所有子节点(包括文本节点和元素节点),返回伪数组。
使用 element.children 可以获取元素的所有子元素节点,返回伪数组。
- 兄弟节点:
使用 element.previousSibling 和 element.nextSibling 可以获取元素的前一个和后一个兄弟节点(包括文本节点)。
使用 element.previousElementSibling 和 element.nextElementSibling 可以获取元素的前一个和后一个兄弟元素节点(仅包括元素节点)。