JavaScript的DOM操作(02)
阿新 • • 發佈:2018-12-05
JavaScript的DOM操作(02)
1.節點的新增操作
<script type="text/javascript"> //新建立一個元素節點, 並把該節點新增為文件中指定節點的子節點 window.onload = function(){ alert(1); //1. document.createElement(elementTagName) //新建立一個元素節點, 返回值為指向元素節點的引用 //<li></li> var liNode = document.createElement("li"); //2. 建立 "廈門" 的文字節點 //document.createTextNode(string) 建立一個文字節點 //引數為文字值, 返回該文字節點的引用. var xmText = document.createTextNode("廈門"); //<li>廈門</li> liNode.appendChild(xmText); var cityNode = document.getElementById("city"); //2. elementNode.appendChild(newChild): 為 elementNode //新新增 newChild 子節點, 該子節點將作為 elementNode 的最後 //一個子節點. cityNode.appendChild(liNode); } </script> <body> <p>你喜歡哪個城市?</p> <ul id="city"><li id="bj" name="BeiJing">北京</li> <li>上海</li> <li>東京</li> <li>首爾</li> </ul> <br><br> <p>你喜歡哪款單機遊戲?</p> <ul id="game"> <li id="rl">紅警</li> <li>實況</li> <li>極品飛車</li> <li>魔獸</li> </ul> <br><br> gender: <input type="radio" name="gender" value="male"/>Male <input type="radio" name="gender" value="female"/>Female <br><br> name: <input type="text" name="username" value="xxx"/> </body>
2.節點的互換操作
<script type="text/javascript"> //測試 replaceChild 方法 window.onload = function(){ alert(1); var bjNode = document.getElementById("bj"); var rlNode = document.getElementById("rl"); var gameNode = document.getElementById("game"); gameNode.replaceChild(bjNode, rlNode); //replaceEach(bjNode, rlNode); /* var cityNode = document.getElementById("city"); //cityNode.replaceChild(rlNode, bjNode); //實現 bj 節點和 rl 節點的互換. var gameNode = document.getElementById("game"); //克隆 bjNode //cloneNode(deep) 若 deep 為true, 則可以克隆子節點 var bjNode2 = bjNode.cloneNode(true); gameNode.replaceChild(bjNode2, rlNode); alert(2); cityNode.replaceChild(rlNode, bjNode); */ } //自定義互換兩個節點的函式 function replaceEach(aNode, bNode){ //1. 獲取 aNode 和 bNode 的父節點. 使用 parentNode 屬性 var aParent = aNode.parentNode; var bParent = bNode.parentNode; if(aParent && bParent){ //2. 克隆 aNode 或 bNode var aNode2 = aNode.cloneNode(true); //3. 分別呼叫 aNode 的父節點和 bNode 的父節點的 replaceChild() //方法實現節點的互換 bParent.replaceChild(aNode2, bNode); aParent.replaceChild(bNode, aNode); } } </script> <body> <p>你喜歡哪個城市?</p> <ul id="city"><li id="bj" name="BeiJing">北京</li> <li>上海</li> <li>東京</li> <li>首爾</li> </ul> <br><br> <p>你喜歡哪款單機遊戲?</p> <ul id="game"> <li id="rl">紅警</li> <li>實況</li> <li>極品飛車</li> <li>魔獸</li> </ul> <br><br> gender: <input type="radio" name="gender" value="male"/>Male <input type="radio" name="gender" value="female"/>Female <br><br> name: <input type="text" name="username" value="xxx"/> </body>
3.節點的移除
<script type="text/javascript"> //測試 removeChild() 方法: 刪除節點 window.onload = function(){ /* alert("1"); var bjNode = document.getElementById("bj"); bjNode.parentNode.removeChild(bjNode); */ //為每個 li 節點新增一個 confirm(確認對話方塊): 確定要刪除 xx 的資訊嗎? //若確定, 則刪除 var liNodes = document.getElementsByTagName("li"); for(var i = 0; i < liNodes.length; i++){ liNodes[i].onclick = function(){ var flag = confirm("確定要刪除" + this.firstChild.nodeValue + "的資訊嗎?"); if(flag){ this.parentNode.removeChild(this); } } } //var flag = confirm("確定要刪除嗎?"); //alert(flag); } </script> <body> <p>你喜歡哪個城市?</p> <ul id="city"><li id="bj" name="BeiJing">北京</li> <li>上海</li> <li>東京</li> <li>首爾</li> </ul> <br><br> <p>你喜歡哪款單機遊戲?</p> <ul id="game"> <li id="rl">紅警</li> <li>實況</li> <li>極品飛車</li> <li>魔獸</li> </ul> <br><br> gender: <input type="radio" name="gender" value="male"/>Male <input type="radio" name="gender" value="female"/>Female <br><br> name: <input type="text" name="username" value="xxx"/> </body>
4.節點的插入
<script type="text/javascript">
//測試 insertBefore() 插入節點
//該方法除了進行插入外, 還有移動節點的功能.
window.onload = function(){
alert("abc");
//1. 把 #rl 插入到 #bj 節點的前面
var cityNode = document.getElementById("city");
var bjNode = document.getElementById("bj");
var rlNode = document.getElementById("rl");
//cityNode.insertBefore(rlNode, bjNode);
var refNode = document.getElementById("se");
//var refNode = document.getElementById("dj");
insertAfter(rlNode, refNode);
}
//把 newNode 插入到 refNode 的後面
function insertAfter(newNode, refNode){
//1. 測試 refNode 是否為其父節點的最後一個子節點
var parentNode = refNode.parentNode;
if(parentNode){
var lastNode = parentNode.lastChild;
//2. 若是: 直接把 newNode 插入為 refNode 父節點的最後一個子節點.
if(refNode == lastNode){
parentNode.appendChild(newNode);
}
//3. 若不是: 獲取 refNode 的下一個兄弟節點, 然後插入到其下一個兄弟
//節點的前面.
else{
var nextNode = refNode.nextSibling;
parentNode.insertBefore(newNode, nextNode);
}
}
}
</script>
<body>
<p>你喜歡哪個城市?</p>
<ul id="city"><li id="bj" name="BeiJing">北京</li>
<li>上海</li>
<li id="dj">東京</li>
<li id="se">首爾</li>
</ul>
<br><br>
<p>你喜歡哪款單機遊戲?</p>
<ul id="game">
<li id="rl">紅警</li>
<li>實況</li>
<li>極品飛車</li>
<li>魔獸</li>
</ul>
<br><br>
gender:
<input type="radio" name="gender" value="male"/>Male
<input type="radio" name="gender" value="female"/>Female
<br><br>
name: <input type="text" name="username" value="xxx"/>
</body>
5.測試 innerHTML 屬性
<script type="text/javascript">
//測試 innerHTML 屬性
window.onload = function(){
var cityNode = document.getElementById("city");
alert(cityNode.innerHTML);
//互換 #city 節點和 #game 節點中的內容.
var tempHTML = cityNode.innerHTML;
var gameNode = document.getElementById("game");
cityNode.innerHTML = gameNode.innerHTML;
gameNode.innerHTML = tempHTML;
}
</script>
<body>
<p>你喜歡哪個城市?</p>
<ul id="city"><li id="bj" name="BeiJing">北京</li>
<li>上海</li>
<li id="dj">東京</li>
<li id="se">首爾</li>
</ul>
<br><br>
<p>你喜歡哪款單機遊戲?</p>
<ul id="game">
<li id="rl">紅警</li>
<li>實況</li>
<li>極品飛車</li>
<li>魔獸</li>
</ul>
<br><br>
gender:
<input type="radio" name="gender" value="male"/>Male
<input type="radio" name="gender" value="female"/>Female
<br><br>
name: <input type="text" name="username" value="x"/>
</body>
6.總結
1. 節點及其型別:
1). 元素節點
2). 屬性節點: 元素的屬性, 可以直接通過屬性的方式來操作.
3). 文字節點: 是元素節點的子節點, 其內容為文字.
2. 在 html 文件的什麼位置編寫 js 程式碼?
0). 直接在 html 頁面中書寫程式碼.
<button id="button" onclick="alert('hello world');">Click Me!</button>
缺點:
①. js 和 html 強耦合, 不利用程式碼的維護
②. 若 click 相應函式是比較複雜的, 則需要先定義一個函式, 然後再在 onclick 屬性中完成對函式的引用, 比較麻煩
1). 一般地, 不能在 body 節點之前來直接獲取 body 內的節點, 因為此時 html 文件樹還沒有載入完成,
獲取不到指定的節點:
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Untitled Document</title>
<script type="text/javascript">
var cityNode = document.getElementById("city");
//列印結果為 null.
alert(cityNode);
</script>
</head>
<body>
......
2). 可以在整個 html 文件的最後編寫類似程式碼, 但這不符合習慣
3). 一般地, 在 body 節點之前編寫 js 程式碼, 但需要利用 window.onload 事件,
該事件在當前文件完全載入之後被觸發, 所以其中的程式碼可以獲取到當前文件的任何節點.
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Untitled Document</title>
<script type="text/javascript">
window.onload = function(){
var cityNode = document.getElementById("city");
alert(cityNode);
};
</script>
</head>
<body>
......
3. 如何來獲取元素節點:
1). **document.getElementById: 根據 id 屬性獲取對應的單個節點
2). **document.getElementsByTagName:
根據標籤名獲取指定節點名字的陣列, 陣列物件 length 屬性可以獲取陣列的長度
3). document.getElementsByName:
根據節點的 name 屬性獲取符合條件的節點陣列,
但 ie 的實現方式和 W3C 標準有差別:
在 html 文件中若某節點(li)沒有 name 屬性,
則 ie 使用 getElementsByName 不能獲取到節點陣列, 但火狐可以.
4). 其它的兩個方法, ie 根本就不支援, 所以不建議使用
4. 獲取屬性節點:
1). **可以直接通過 cityNode.id 這樣的方式來獲取和設定屬性節點的值
2). 通過元素節點的 getAttributeNode 方法來獲取屬性節點,
然後在通過 nodeValue 來讀寫屬性值
5. 獲取元素節點的子節點(**只有元素節點才有子節點!!):
1). childNodes 屬性獲取全部的子節點, 但該方法不實用. 因為如果要獲取指定的節點
的指定子節點的集合, 可以直接呼叫元素節點的 getElementsByTagName() 方法來獲取.
2). firstChild 屬性獲取第一個子節點
3). lastChild 屬性獲取最後一個子節點
6. 獲取文字節點:
1). 步驟: 元素節點 --> 獲取元素節點的子節點
2). 若元素節點只有文字節點一個子節點,
例如 <li id="bj" name="BeiJing">北京</li>, <p>你喜歡哪個城市?</p>,
可以先獲取到指定的元素節點 eleNode,
然後利用 eleNode.firstChild.nodeValue 的方法來讀寫其文字節點的值
7. 節點的屬性:
1). nodeName: 代表當前節點的名字. 只讀屬性.
**如果給定節點是一個文字節點, nodeName 屬性將返回內容為 #text 的字串
2). nodeType:返回一個整數, 這個數值代表著給定節點的型別.
只讀屬性. 1 -- 元素節點, 2 -- 屬性節點, 3 -- 文字節點
**3). nodeValue:返回給定節點的當前值(字串). 可讀寫的屬性
①. 元素節點, 返回值是 null.
②. 屬性節點: 返回值是這個屬性的值
③. 文字節點: 返回值是這個文字節點的內容
8. 建立一個元素節點:
1). createElement(): 按照給定的標籤名建立一個新的元素節點. 方法只有一個引數:被建立的元素節點的名字, 是一個字串.
方法的返回值:是一個指向新建節點的引用指標. 返回值是一個元素節點, 所以它的 nodeType 屬性值等於 1.
**新元素節點不會自動新增到文件裡, 它只是一個存在於 JavaScript 上下文的物件.
9. 建立一個文字節點:
1). createTextNode(): 建立一個包含著給定文字的新文字節點. 這個方法的返回值是一個指向新建文字節點引用指標. 它是一個文字節點, 所以它的 nodeType 屬性等於 3.
方法只有一個引數:新建文字節點所包含的文字字串. 新元素節點不會自動新增到文件裡
10. 為元素節點新增子節點:
1). appendChild(): var reference = element.appendChild(newChild): 給定子節點 newChild 將成為給定元素節點 element 的最後一個子節點.
方法的返回值是一個指向新增子節點的引用指標.
11. 節點的替換:
1). replaceChild(): 把一個給定父元素裡的一個子節點替換為另外一個子節點
var reference = element.replaceChild(newChild,oldChild);
返回值是一個指向已被替換的那個子節點的引用指標
2). 該節點除了替換功能以外還有移動的功能.
3). 該方法只能完成單向替換, 若需要使用雙向替換, 需要自定義函式:
/**
* 互換 aNode 和 bNode
* @param {Object} aNode
* @param {Object} bNode
*/
function replaceEach(aNode, bNode){
if(aNode == bNode){
return;
}
var aParentNode = aNode.parentNode;
//若 aNode 有父節點
if(aParentNode){
var bParentNode = bNode.parentNode;
//若 bNode 有父節點
if(bParentNode){
var tempNode = aNode.cloneNode(true);
bParentNode.replaceChild(tempNode, bNode);
aParentNode.replaceChild(bNode, aNode);
}
}
}
12. 插入節點:
1). insertBefore(): 把一個給定節點插入到一個給定元素節點的給定子節點的前面
var reference = element.insertBefore(newNode,targetNode);
節點 newNode 將被插入到元素節點 element 中並出現在節點 targetNode 的前面. 節點 targetNode 必須是 element 元素的一個子節點。
2). 自定義 insertAfter() 方法
/**
* 將 newChild 插入到 refChild 的後邊
* @param {Object} newChild
* @param {Object} refChild
*/
function insertAfter(newChild, refChild){
var refParentNode = refChild.parentNode;
//判斷 refChild 是否存在父節點
if(refParentNode){
//判斷 refChild 節點是否為其父節點的最後一個子節點
if(refChild == refParentNode.lastChild){
refParentNode.appendChild(newChild);
}else{
refParentNode.insertBefore(newChild, refChild.nextSibling);
}
}
}
13. 刪除節點:
1). removeChild(): 從一個給定元素裡刪除一個子節點
var reference = element.removeChild(node);
返回值是一個指向已被刪除的子節點的引用指標. 某個節點被 removeChild() 方法刪除時, 這個節點所包含的所有子節點將同時被刪除.
如果想刪除某個節點, 但不知道它的父節點是哪一個, parentNode 屬性可以幫忙。
14. innerHTML屬性:
1). 瀏覽器幾乎都支援該屬性, 但不是 DOM 標準的組成部分. innerHTML 屬性可以用來讀, 寫某給定元素裡的 HTML 內容
15. 其它屬性, 參看 API: nsextSibling, previousSibling 等