從零開始學 Web 之 DOM(四)節點
大家好,這裏是「 Daotin的夢囈 」從零開始學 Web 系列教程。此文首發於「 Daotin的夢囈 」公眾號,歡迎大家訂閱關註。在這裏我會從 Web 前端零基礎開始,一步步學習 Web 相關的知識點,期間也會分享一些好玩的項目。現在就讓我們一起進入 Web 前端學習的冒險之旅吧!
一、節點
1、節點的概念
頁面中的所有內容,包括標簽,屬性,文本(文字,空格,回車,換行等),也就是說頁面的所有內容都可以叫做節點。
2、節點相關的屬性
2.1、節點分類
標簽節點:比如 div 標簽,p 標簽等。
屬性節點:比如 class,value 等。
文本節點:比如閉合標簽中的文本內容。
2.2、節點屬性
nodeType:節點的類型,它的值有 1,2,3 三種。
? 標簽節點:值為 1
? 屬性節點:值為 2
? 文本節點:值為 3
nodeName:節點的名字
? 標簽節點:大寫的標簽名字
? 屬性節點:小寫的屬性名字
? 文本節點:#text
nodeValue:節點的值
? 標簽節點:null
? 屬性節點:屬性的值
? 文本節點:文本內容
3、獲取相關節點
3.1、獲取父節點和父元素
父節點只能是標簽,不能是屬性節點和文本節點,所以父節點也是父元素。
<body>
<div id="dv">
<p id="pid" ></p>
<span></span>
</div>
<script src="common.js"></script>
<script>
var dvObj = my$("pid");
console.log(dvObj.parentNode);
console.log(dvObj.parentElement);
</script>
</body>
parentNode
:獲取元素的父節點。parentElement:獲取元素的父元素。
3.2、獲取子節點和子元素
<body>
<div id="dv">
<p id="pid">p標簽</p>
<span>span標簽</span>
<ul>
<li>li標簽</li>
<li>li標簽</li>
<li>li標簽</li>
<li>li標簽</li>
<li>li標簽</li>
</ul>
</div>
<script src="common.js"></script>
<script>
var dvObj = my$("dv");
// 獲取子節點
console.log(dvObj.childNodes); // 7個
// 獲取子元素
console.log(dvObj.children); // 3個
</script>
</body>
childNodes:獲取所有子節點(包括標簽,屬性,節點)
children:獲取所有子元素(僅包括標簽)
3.3、通過屬性的名字獲取屬性節點
<body>
<div id="dv">
<p id="pid">p標簽</p>
<span>span標簽</span>
<ul>
<li>li標簽</li>
<li>li標簽</li>
<li>li標簽</li>
<li>li標簽</li>
<li>li標簽</li>
</ul>
</div>
<script src="common.js"></script>
<script>
var dvObj = my$("dv");
console.log(dvObj.getAttributeNode("id")); // id="dv"
</script>
</body>
getAttributeNode:可以獲取屬性節點。
3.4、獲取節點和元素的12行代碼
<body>
<div id="dv">
<p id="pid">p標簽</p>
<span>span標簽</span>
<ul id="uu">海
<li>li標簽</li>內
<li>li標簽</li>存
<li id="three">li標簽</li>知己
<li>li標簽</li>天涯
<li>li標簽</li>若比鄰
</ul>
</div>
<script src="common.js"></script>
<script>
var ulObj = my$("uu");
// 父節點
console.log(ulObj.parentNode);
// 父元素
console.log(ulObj.parentElement);
// 子節點
console.log(ulObj.childNodes);
// 子元素
console.log(ulObj.children);
// ------------------------------------------------
// 第一個子節點
console.log(ulObj.firstChild);
// 第一個子元素
console.log(ulObj.firstElementChild);
// 最後一個子節點
console.log(ulObj.lastChild);
// 最後一個子元素
console.log(ulObj.lastElementChild);
// 某個元素的前一個兄弟節點
console.log(my$("three").previousSibling);
// 某個元素的前一個兄弟元素
console.log(my$("three").previousElementSibling);
// 某個元素的後一個兄弟節點
console.log(my$("three").nextSibling);
// 某個元素的後一個星弟元素
console.log(my$("three").nextElementSibling);
</script>
</body>
1、以上前四個,chrome, firefox, IE8 都支持
2、後面八個,chrome,firefox支持,IE8下,所有獲取節點的操作都獲取的是元素,所有獲取元素的操作都是 undefined。
3.5、總結
- 獲取父子節點和元素的操作,chrome, firefox, IE8 都支持;
- 獲取特殊子節點或者子元素和兄弟節點和元素操作,IE8 中所有的節點操作都是元素操作,所有的元素操作都是 undefined。
4、通過節點操作元素
通過節點操作元素的背景顏色
// 通過節點設置p標簽的背景顏色為藍色
<body>
<input type="button" value="變色" id="btn">
<div id="dv">
<p>p標簽</p>
<span>span標簽</span>
<p>p標簽</p>
<span>span標簽</span>
<p>p標簽</p>
</div>
<script src="common.js"></script>
<script>
my$("btn").onclick = function () {
var dvObj = my$("dv");
var nodes = dvObj.childNodes;
for(var i=0; i<nodes.length; i++) {
if((nodes[i].nodeType === 1) && (nodes[i].nodeName === "P")) {
nodes[i].style.backgroundColor = "blue";
}
}
};
</script>
</body>
通過節點屬性來區分節點和元素。
5、封裝節點兼容代碼
<body>
<input type="button" value="變色" id="btn">
<ul id="uu">
<li>復仇者聯盟1</li>
<li>復仇者聯盟2</li>
<li>復仇者聯盟3</li>
<li id="ii">復仇者聯盟4</li>
<li>復仇者聯盟5</li>
<li>復仇者聯盟6</li>
<li>復仇者聯盟7</li>
<li>復仇者聯盟8</li>
</ul>
<script src="common.js"></script>
<script>
// 獲取任意一個父元素的第一個子元素
function getFirstElement(element) {
if(element.firstElementChild) {
return element.firstElementChild;
} else { // 主要考慮到多個文本節點的影響
var node = element.firstChild;
while((node) && (node.nodeType !== 1)) {
node = node.nextSibling;
}
return node;
}
}
// 獲取任意一個父元素的最後一個子元素
function getLastElement(element) {
if(element.lastElementChild) {
return element.lastElementChild;
} else { // 主要考慮到多個文本節點的影響
var node = element.lastChild;
while((node) && (node.nodeType !== 1)) {
node = node.previousSibling;
}
return node;
}
}
// 獲取任意一個元素的前一個兄弟元素
function getPreviousElement(element) {
if(element.previousElementSibling) {
return element.previousElementSibling;
} else { // 主要考慮到多個文本節點的影響
var node = element.previousSibling;
while((node) && (node.nodeType !== 1)) {
node = node.previousSibling;
}
return node;
}
}
// 獲取任意一個元素的後一個兄弟元素
function getNextElement(element) {
if(element.nextElementSibling) {
return element.nextElementSibling;
} else { // 主要考慮到多個文本節點的影響
var node = element.nextSibling;
while((node) && (node.nodeType !== 1)) {
node = node.nextSibling;
}
return node;
}
}
// 測試
console.log(getFirstElement(my$("uu")).innerText);
console.log(getLastElement(my$("uu")).innerText);
console.log(getPreviousElement(my$("ii")).innerText);
console.log(getNextElement(my$("ii")).innerText);
</script>
</body>
主要是兼容chrome 和 IE8 之間的差異,其次以獲取任意一個父元素的第一個子元素為例,之所以不在 else 裏面直接使用
return element.firstChild;
主要考慮到標簽之間可能有多個文本節點的影響。
從零開始學 Web 之 DOM(四)節點