[1]創建節點 [2]插入節點 [3]移除節點 [4]替換節點 [5]複製節點 ...
×
目錄
[1]創建節點 [2]插入節點 [3]移除節點[4]替換節點[5]複製節點前面的話
一般地,提起操作會想到“增刪改查”這四個字,而DOM節點操作也類似地對應於此,接下來將詳細介紹DOM的節點操作方法
前提
DOM提供節點操作的方法是因為DOM節點關係指針都是只讀的
下列代碼中想通過修改myUl的父級節點來修改其節點關係,但由於parentNode屬性是只讀的,所以修改無效,在IE8-瀏覽器下甚至會報錯
<div id="myDiv"></div> <ul id="myUl"> <li id="myli"></li> </ul> <script> console.log(myUl.parentNode);//<body> myUl.parentNode = myDiv; //標準瀏覽器下,依然返回<body>;而IE8-瀏覽器則會報錯 console.log(myUl.parentNode); </script>
DOM節點操作方法包括創建節點、插入節點、刪除節點、替換節點、查看節點和複製節點。查看節點指的是查看節點之間的關係,在節點關係部分已經做過詳細介紹,就不再贅述
創建節點
createElement
document.createElement()方法可以創建新元素。這個方法接受一個參數,即要創建元素的標簽名,這個標簽名在HTML文檔中不區分大小寫
var oDiv = document.createElement("div"); console.log(oDiv);//<div>
IE8-瀏覽器可以為這個方法傳入完整的元素標簽,也可以包含屬性
var oDiv = document.createElement('<div id="box"></div>'); console.log(oDiv.id);//'box'
所有節點都有一個ownerDocument的屬性,指向表示整個文檔的文檔節點document;在使用createElement()方法創建新元素的同時,也為新元素設置了ownerDocument屬性
<div id="myDiv"></div> <script> console.log(myDiv.ownerDocument);//document var newDiv = document.createElement('div'); console.log(newDiv.ownerDocument);//document console.log(newDiv.ownerDocument === myDiv.ownerDocument);//true </script>
插入節點
appendChild
appendChild()方法用於向childNodes列表的末尾添加一個節點,並返回新增節點。添加節點後,childNodes中的新增節點、父節點和以前的最後一個子節點的關係指針都會相應地得到更新
<div id="box"></div> <script> var oBox = document.getElementById('box'); var newNode = document.createElement('ul'); var returnedNode = oBox.appendChild(newNode); console.log(returnedNode.nodeName);//UL console.log(returnedNode == newNode);//true console.log(returnedNode == oBox.lastChild);//true </script>
如果插入的節點已經是文檔的一部分了,那結果就是將該節點從原來的位置轉移到新位置
<body> <div id="oldDiv">第一個div</div> <div id="newDiv">第二個div</div> <button id="btn">變換位置</button> <script> btn.onclick = function(){ document.body.appendChild(newDiv); } </script> </body>
insertBefore
insertBefore()方法接收兩個參數:要插入的節點和作為參照的節點。插入節點後,被插入的節點會變成參照節點的前一個兄弟節點(previousSibling),同時被方法返回。如果參照節點是null,則insertBefore()與appendChild()方法執行相同的操作。同樣地,如果插入的節點已經是文檔的一部分了,那結果就是將該節點從原來的位置轉移到新位置
referenceNode.parentNode.insertBefore(newNode,referenceNode);
<ul id="myUl" style="border:1px solid black;"> <li id="myLi"> <div id='oldDiv'>oldDiv</div> </li> </ul> <button id="btn1">插入oldDiv的前面</button> <button id="btn2">插入myUl的前面</button> <button id="btn3">插到oldDiv的裡面</button> <script> var oDiv = document.createElement('div'); oDiv.innerHTML = 'newDiv'; btn1.onclick = function(){ console.log(myLi.insertBefore(oDiv,oldDiv));//<div>newDiv</div> } btn2.onclick = function(){ console.log(document.body.insertBefore(oDiv,myUl));//<div>newDiv</div> } btn3.onclick = function(){ console.log(oldDiv.insertBefore(oDiv,null));//<div>newDiv</div> } </script>
【小效果】
<ul class="list" id="list"> <li class="in">1</li> <li class="in">2</li> <li class="in">3</li> <li class="in">4</li> <li class="in">5</li> <li class="in">6</li> </ul> <script> var oList = document.getElementById('list'); //新增一個li元素 var oAdd = document.createElement('li'); //設置新增元素的css樣式 oAdd.className = "in"; oAdd.style.cssText = 'background-color:red;border-radius:50%'; //添加到oList中 oList.insertBefore(oAdd,null); var num = -1; var max = oList.children.length; function incrementNumber(){ num++; //oList.getElementsByTagName('li')[max]相當於null,所以不報錯 oList.insertBefore(oAdd,oList.getElementsByTagName('li')[num]); if(num == max){ num = -1; } if(num == 0){ num = 1; } setTimeout(incrementNumber,1000); } setTimeout(incrementNumber,1000); </script>
insertAfter
由於不存在insertAfter方法,如果要插在當前節點的某個子節點後面,可以用insertBefore()和appendChild()封裝方法
function insertAfter(newElement,targetElement){ var parent = targetElement.parentNode; if(parent.lastChild == targetElement){ parent.appendChild(newElement); }else{ parent.insertBefore(newElement,targetElement.nextSibling) } }
<div id='oldDiv'>old</div> <button id="btn">增加節點</button> <script> function insertAfter(newElement,targetElement){ var parent = targetElement.parentNode; if(parent.lastChild == targetElement){ return parent.appendChild(newElement); }else{ return parent.insertBefore(newElement,targetElement.nextSibling) } } var newDiv = document.createElement('div'); newDiv.innerHTML = 'new'; btn.onclick = function(){ insertAfter(newDiv,oldDiv); } </script>
insertAdjacentHTML
insertAdjacentHTML()方法作為終級辦法,相當於前面三個方法的綜合。該方法接收兩個參數:插入的位置和要插入的HTML文本
第一個參數必須是下列值之一,且這些值都必須是小寫形式:
"beforebegin" 在當前元素之前插入一個緊鄰的同級元素 "afterbegin" 在當前元素之下插入一個新的子元素或在第一個子元素之前再插入新的子元素 "beforeend" 在當前元素之下插入一個新的子元素或在最後一個子元素之後再插入新的子元素 "afterend" 在當前元素之後插入一個緊鄰的同級元素
第二個參數是一個HTML字元串,如果瀏覽器無法解析字元串,就會拋出錯誤
[註意]該方法無返回值
<div id='target' style="border: 1px solid black;">This is the element content</div> <button>beforebegin</button> <button>afterbegin</button> <button>beforeend</button> <button>afterend</button> <script> var btns = document.getElementsByTagName('button'); for(var i = 0 ; i < 4; i++){ btns[i].onclick = function(){ var that = this; target.insertAdjacentHTML(that.innerHTML,'<span id="test">測試</span>') } } </script>
移除節點
removeChild
removeChild()方法接收一個參數,即要移除的節點,被移除的節點成為方法的返回值
<div id="myDiv">等待移除的節點</div> <button id="btn">移除節點</button> <script> btn.onclick = function(){ document.body.removeChild(myDiv); } </script>
下麵代碼可以移除當前節點的所有子節點
var element = document.getElementById("top"); while (element.firstChild) { element.removeChild(element.firstChild); }
【小效果】
<button id="btn">開始刪除節點</button> <ul class="list" id="list"> <li class="in">1</li> <li class="in">2</li> <li class="in">3</li> <li class="in">4</li> <li class="in">5</li> <li class="in">6</li> </ul> <script> var oList = document.getElementById('list'); function incrementNumber(){ //獲取oList中子元素的個數 var len = oList.getElementsByTagName('li').length; //如果長度不為0 if(len){ //刪除最後一個子元素 oList.removeChild(oList.getElementsByTagName('li')[len-1]); //再次調用計時器 setTimeout(incrementNumber,1000); } } btn.onclick = function(){ //1s後執行函數incrementNumber setTimeout(incrementNumber,1000); } </script>
替換節點
replaceChild
replaceChild()接收的兩個參數是要插入的節點和要替換的節點,要替換的節點將由這個方法返回並從文檔樹中移除,同時由要插入的節點占據其位置
oldChild.parentNode.replaceChild(newChild, oldChild);
<div id="div1">1</div> <div id="div2">2</div> <div id="div3">3</div> <button id="btn1">新增節點替換(4替換2)</button> <button id="btn2">原有節點替換(3替換1)</button> <script> btn2.onclick = function(){ document.body.replaceChild(div3,div1); } btn1.onclick = function(){ var div4 = document.createElement('div'); div4.innerHTML = '4'; document.body.replaceChild(div4,div2); } </script>
【小效果】
<button id="btn">開始替換節點</button> <ul class="list" id="list"> <li class="in">1</li> <li class="in">2</li> <li class="in">3</li> <li class="in">4</li> <li class="in">5</li> <li class="in">6</li> </ul> <script> var oList = document.getElementById('list'); //新增一個li元素 var oAdd = document.createElement('li'); //設置新增元素的css樣式 oAdd.className = "in"; oAdd.style.cssText = 'background-color:red;border-radius:50%'; btn.onclick = function(){ //1s後oAdd替換第0個li setTimeout(function(){ oList.replaceChild(oAdd,document.getElementsByTagName('li')[0]); //1s後執行incrementNumber函數 setTimeout(incrementNumber,1000); },1000); } function incrementNumber(){ //獲取oList中第1個li var oLi1 = document.getElementsByTagName('li')[1]; //若存在則進行替換處理 if(oLi1){ oList.replaceChild(oAdd,oLi1); setTimeout(incrementNumber,1000); } } </script>
複製節點
cloneNode
cloneNode方法用於克隆一個節點。它接受一個布爾值作為參數,表示是否執行深複製。在參數為true時,執行深複製,也就是複製節點及整個子節點樹。在參數為false的情況下,執行淺複製,即複製節點本身。複製後返回的節點副本屬於文檔所有,但並沒有為它指定父節點。若參數為空,也相當於false
[註意]cloneNode()方法不會複製添加到DOM節點中的javascript屬性,例如事件處理程式等。這個方法只複製特性和子節點,其他一切都不會複製
<ul id="list"> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> <li>6</li> </ul> <script> var oList = document.getElementById('list'); oList.index = 0; var deepList = oList.cloneNode(true); //成功複製了子節點 console.log(deepList.children.length);//6 //但並沒有複製屬性 console.log(deepList.index);//undefined var shallowList = oList.cloneNode(); //淺複製不複製子節點 console.log(shallowList.children.length);//0 </script>