JS之DOM篇-节点关系
DOM可以把任何HTML描绘成一个由多层节点构成的结构,节点之间的关系构成了层次,所有的页面标记都可以看做一个以特定节点为根节点的树形结构,这种结构被称作DOM树
节点中的各种关系可以用传统的家族关系来描述,相当于把文档树比喻成家谱
属性
parentNode
每个节点都有一个parentNode属性,指向它的父节点。父节点只可能有三种类型: element节点、document节点、documentFragment节点,如果不存在则返回null
<body>
<div id="test">test</div>
<script>
console.log(test.parentNode) // body
console.log(document.body.parentNode) // html
console.log(document.documentElement.parentNode) // document
console.log(document.parentNode) // null
var testDom = document.getElementById('test')
var fragment = document.createDocumentFragment()
fragment.appendChild(testDom)
console.log(testDom.parentNode) // document-fragment
</script>
</body>
parentElement
parentElement返回父元素节点
<body>
<div id="test">test</div>
<script>
console.log(test.parentElement) // body
console.log(document.body.parentElement) // html
console.log(document.documentElement.parentElement) // null
console.log(document.parentElement) // null
</script>
</body>
注意: 在IE浏览器中,只有Element元素节点才有该属性,其他浏览器则是所有类型的节点都有该属性
childNodes
childNodes是一个只读的NodeList对象,保存着父节点下的第一层子节点
<ul id="list">
<li><span>1</span></li>
<li>2</li>
</ul>
<script>
console.log(list.childNodes) // [text, li, text, li, text]
</script>
children
children是一个只读的HTMLCollection对象,它保存着父节点下的第一层子元素节点
<ul id="list">
<li><span>1</span></li>
<li>2</li>
</ul>
<script>
console.log(list.children) // [li, li]
</script>
childElementCount
childElementCount返回子元素节点的个数,等价于children.length
<ul id="list">
<li><span>1</span></li>
<li>2</li>
</ul>
<script>
console.log(list.childElementCount) // 2
</script>
firstChild
第一个子节点
lastChild
最后一个子节点
firstElementChild
第一个元素子节点
lastElementChild
最后一个元素子节点
<ul id="list">
<li><span>1</span></li>
<li>2</li>
</ul>
<script>
console.log(list.firstChild) // #text
console.log(list.lastChild) // #text
console.log(list.firstElementChild) // <li><span>1</span></li>
console.log(list.lastElementChild) // <li>2</li>
</script>
nextSibling
当前节点的后一个节点
previousSibling
当前节点的前一个节点
nextElementSibling
当前节点后一个元素节点
previousElementSibling
当前节点前一个元素节点
<ul id="list">
<li><span>1</span></li>
<li id="two">2</li>
<li>3</li>
</ul>
<script>
console.log(two.nextSibling) // #text
console.log(two.previousSibling) // #text
console.log(two.nextElementSibling) // <li><span>1</span></li>
console.log(two.previousElementSibling) // <li>3</li>
</script>
方法
hasChildNodes()
hasChildNodes()方法表示当存在子节点时返回true,否则返回false
<div id="test">1</div>
<div id="test2"></div>
<script>
console.log(test.hasChildNodes()) // true
console.log(test2.hasChildNodes()) // false
</script>
contains()
contains(node)方法表示参数节点是否是当前节点的后代节点,它接受一个节点作为参数,返回一个布尔值
<ul id="list">
<li><span id="one">1</span></li>
<li id="two">2</li>
</ul>
<script>
console.log(list.contains(one), list.contains(two)) // true true
</script>
注意: IE和safari不支持document.contains()方法,只支持元素节点的contains()方法
compareDocumentPosition()
compareDocumentPosition方法用于确定节点间的关系,返回一个表示该关系的位掩码
000000 0 两个节点相同
000001 1 两个节点不在同一个文档(即有一个节点不在当前文档)
000010 2 参数节点在当前节点的前面
000100 4 参数节点在当前节点的后面
001000 8 参数节点包含当前节点
010000 16 当前节点包含参数节点
100000 32 浏览器的私有用途
<div id="box">
<ul id="list">
<li id="one">one</li>
<li id="two">two</li>
</ul>
</div>
<script>
// list节点被box节点包含,并且位于box节点后面,所以16+4=20
console.log(box.compareDocumentPosition(list)) // 20
// box节点包含list节点,并且位于list节点前面,所以8+2=10
console.log(list.compareDocumentPosition(box)) // 10
console.log(list.compareDocumentPosition(list)) // 0
console.log(one.compareDocumentPosition(two)) // 4
console.log(two.compareDocumentPosition(one)) // 2
</script>
isSameNode()和isEqualNode()
这两个方法都接收一个节点作为参数,isSameNode()方法表示当参数节点和引用节点相同时返回true,isEqualNode()方法表示当参数节点和引用节点相等时返回true
相同表示的是两个节点引用的是同一个对象
相等表示两个节点类型一样并且属性相等,但不一定是同一个对象
<script>
var div1 = document.createElement('div')
div1.setAttribute('title','test')
var div2 = document.createElement('div')
div2.setAttribute('title','test')
console.log(div1.isSameNode(div1)) // true
console.log(div1.isSameNode(div2)) // false
console.log(div1.isEqualNode(div2)) // true
</script>