理解DOM
Node类型
JavaScript中的所有类型的节点类型(12种)都继承自Node类型,所有节点类型(nodeType)都共享着相同的基本属性和方法
节点关系
大部分节点都childNodes属性,其中保存这一个 NodeList对象
📌 NodeList对象是一个类数组对象,用于保存一组有序的节点,可以通过位置访问这些节点,大多数情况下NodeList是实时集合,是动态的,但是 parentNode.querySelector()返回的NodeList是静态的
操作节点
节点类型(nodeType)
Document 类型
表示文档
💡 常见应用是作为HTMLDocument实例的document对象(HTMLDcument继承自Document类型)
Element类型
用于表现XML或HTML元素
💡所有HTML元素都由HTMLElement类型或者它的子类型表示
var el = document.createElement('div')el.className = 'message'document.body.appendChild(el)
Text类型
表示文本节点,可以包含转义后的HTML字符,但不能包含HTML代码
💡 操作文本节点
可以通过nodeValue属性或data属性访问文本节点包含的文本,这两个属性包含的值相同,对nodeValue的修改也会通过data反映出来,反之亦然。
操作方法:
💡 创建文本节点
document.createTextNode(),接收一个参数—要插入节点中的文本
var textNode = document.createTextNode('hello')
DocumentFragment 类型
文档片段,在文档中没有对应的标记,可以包含和控制节点,但不会向文档那样占用额外的资源
文档片段不能直接添加到文档,可以将它作为一个“仓库”使用,在里面保存将来可能会添加到文档中的节点
如下所示,如果想向指定 ul 元素内添加三个li标签,逐个添加会导致浏览器反复渲染,为了避免就可以采用文档片段保存要创建的列表项,然后一次性添加
<ul id="list"></ul>// 创建文档片段var fragment = document.createDocumentFragment()var ul = document.getElementById('list')var li = nullfor(var i=0; i < 3; i++) {li = document.createElement('li')li.appendChild(document.createTextNode('Item' + (i+1)))fragment.appendChild(li)}ul.appendChild(fragment)
Attr类型
元素的特性在DOM中以Attr类型来表示,特性就是存在于元素attributes属性中的节点,但是尽管属于节点,但却不认为是DOM文档树的一部分
不建议使用attributes属性访问特性,使用以下操作方法更为方便
- getAttribute()
- setAttribute()
- removeAttribute()
使用document.createAttribute()并传入特性的名称可以创建新的特性节点
// 创建元素节点并传入标签名称var el = document.createElement('div')// 创建特性节点,并传入特性名称var attr = document.createAttribute('self')// 给特性赋值attr.value = 'tip'// 将特性节点插入元素节点el.setAttributeNode(attr)// 读取元素特性节点el.attributes['self'].value // "tip"el.getAttributeNode('self').value // tipel.getAttribute('self') // 👉 "tip"
📌拓展:NodeList、NamedNodeMap、HTMLCollection
NodeList表示节点的集合NamedNodeMap表示属性节点 Attr 对象的集合HTMLCollection表示包含了指定元素的集合
这三个集合都是动态的,每当文档结构发生变化时,它们都会得到更新,因此它们始终保存着最新最准确的信息。
下列代码会导致无限循环
let divs = document.getElementsByTagName('div')// 取得文档中所有元素<div>元素的 HTMLCoolection,是动态的let ilet div// 每循环一次新增一个div,所有divs.length每循环一次都会新增1// 这样 i 就永远不能打破循环条件for ( i=0; i < divs.length; i++) {div = document.createElement('div')document.body.appendChild(div)}
改进:使用NodeList的属性length初始化第二个变量
let divs = document.getElementsByTagName('div')let len // 新增let ilet divfor (i=0; i < len; i++) {div = document.createElement('div')document.body.appendChild(div)}
