本文主要讲解DOM常用的CURD操作,appendChild(往后追加节点),insertBefore(往前追加节点),removeChild(移除节点),replaceChild(替换节点),cloneNode(克隆节点)的语法与实战应用
一、appendChild: 向元素的内部最后面增加一个节点,或者移动一个现有的节点到元素的内部最后面
用法:
someNode.appendChild( newNode )
someNode通常为元素的父节点
返回值:
返回新增加的节点
1 <input type="text" name="" id="txt"> 2 <input type="button" value="添加" id="add"> 3 <ul id="box"></ul> 4 <script> 5 var oBtn = document.querySelector("#add"); 6 var oTxt = document.querySelector("#txt"); 7 var oBox = document.querySelector("#box"); 8 oBtn.onclick = function () { 9 var oLi = document.createElement( "li" ); 10 oLi.innerHTML = oTxt.value; 11 var returnNode = oBox.appendChild( oLi ); 12 console.log( returnNode === oLi ); //true 13 console.log( returnNode === oBox.lastChild );//true 14 } 15 </script>
上例,把文本框的内容当做一个新节点,添加在id为box的元素的最后面,返回值returnNode就是新增加的节点,
所以 第12行和第13行的返回值为ture, lastChild表示元素的最后一个子节点
如果appendChild后面的参数是文档现有的节点,那么表示把当前节点移动到父元素的最后面
1 <input type="button" value="移动" id="btn"> 2 <ul id="box"> 3 <li><a href="javascript:;">王朝</a></li> 4 <li><a href="javascript:;">马汉</a></li> 5 <li><a href="javascript:;">张龙</a></li> 6 <li><a href="javascript:;">赵虎</a></li> 7 <li><a href="javascript:;">ghostwu</a></li> 8 </ul> 9 <script> 10 var oBtn = document.getElementById("btn"); 11 var oBox = document.getElementById("box"); 12 oBtn.onclick = function () { 13 var firstChild = oBox.firstElementChild || oBox.firstChild; 14 var lastChild = oBox.lastElementChild || oBox.lastChild; 15 var returnNode = oBox.appendChild( firstChild ); 16 firstChild = oBox.firstElementChild || oBox.firstChild; 17 lastChild = oBox.lastElementChild || oBox.lastChild; 18 console.log( returnNode === firstChild ); //false 19 console.log( returnNode === lastChild ); //true 20 } 21 </script>
上例,每次点击按钮,把第一个节点移动到最后,所以在第18行为false, 因为移动之后,他就不是第一个节点了,而变成最后一个节点,所以第19行比较结果为true
二、insertBefore:向一个元素前面追加节点
用法:
someNode.insertBefore( newNode, referNode );
第一个参数: newNode,需要插入的节点
第二个参数: referNode, 参考节点,即:newNode会插入到这个参考节点的前面,
注意:如果第二个参数为null, 效果等同于someNode.appendChild( newNode )
返回值:
新插入的节点
1 <input type="text" id="txt"> 2 <input type="button" value="添加" id="add"> 3 <ul id="box"></ul> 4 <script> 5 var G = function ( id ){ return document.getElementById( id ) }; 6 var GG = function ( id, tag ){ return G(id).getElementsByTagName(tag) }; 7 var oTxt = G( "txt" ), 8 oBox = G( "box" ), 9 oAdd = G( "add" ) 10 aLi = GG( 'box', 'li' ); 11 oAdd.onclick = function(){ 12 var oLi = document.createElement("li"); 13 oLi.innerHTML = oTxt.value, 14 returnNode = null; 15 //等价于oBox.appendChild( oLi ) 16 // oBox.insertBefore( oLi, null ); 17 // oBox.appendChild( oLi ); 18 if( aLi[0] ) { 19 returnNode = oBox.insertBefore( oLi, aLi[0] ); 20 }else { 21 returnNode = oBox.insertBefore( oLi, null ); 22 } 23 console.log( returnNode ); 24 } 25 </script>
三、removeChild: 移除一个节点
someNode.removeChild( node )
someNode通常为父元素,node就是父元素下面的一个元素
返回值: 当前被移除的元素
1 <input type="text" name="" id="txt"> 2 <input type="button" value="移除" id="remove"> 3 <ul> 4 <li>1</li> 5 <li>2</li> 6 <li>3</li> 7 <li>4</li> 8 </ul> 9 <script> 10 var oRemove = document.querySelector( "#remove" ); 11 var oUl = document.querySelector( "ul" ); 12 oRemove.onclick = function(){ 13 var n = parseInt( document.querySelector("#txt").value ); 14 var returnNode = oUl.removeChild( oUl.children[n] ); 15 console.log( returnNode ); 16 } 17 </script>
上例,在输入框中, 输入需要移除的子节点的索引,即可完成移除节点操作.
四、replaceChild: 用新节点去替换已经存在的节点
用法
someNode.replaceChild( newNode, node )
第一个参数:新节点
第二个参数: 被替换的节点
返回值: 返回当前被替换的子节点
下例,有点小复杂,用了节点缓存(设计模式中的享元模式)提高替换节点的性能,虽然只有8个节点,如果是上万个节点,会有明显的提高.
1 <input type="button" value="替换" id="replace"> 2 <br> 3 <span>第1个元素</span> 4 <span>第2个元素</span> 5 <span>第3个元素</span> 6 <span>第4个元素</span> 7 <span>第5个元素</span> 8 <span>第6个元素</span> 9 <span>第7个元素</span> 10 <span>第8个元素</span> 11 <script> 12 var oReplace = document.querySelector("#replace"), 13 aSpan = document.querySelectorAll("span"), 14 page = 0, //当前页 15 perPage = 4, //每次替换4个 16 total = Math.ceil(aSpan.length / perPage); //总页数 17 18 var cache = (function () { 19 var aEle = []; 20 var create = function () { 21 var oDiv = document.createElement("div"); 22 aEle.push(oDiv); 23 return oDiv; 24 }; 25 return { 26 getDiv: function () { 27 if (aEle.length < 4) { 28 console.log(1); 29 return create(); 30 } else { 31 console.log(2); 32 var oDiv = aEle.shift(); 33 aEle.push(oDiv); 34 return oDiv; 35 } 36 } 37 }; 38 })(); 39 var aCacheSpan = []; 40 oReplace.onclick = function () { 41 var oDiv = null; 42 page++; 43 if (page < 3) { 44 if (aCacheSpan.length > 0) { 45 var oBox = document.querySelector('div'); 46 for (var i = 0, len = aCacheSpan.length; i < len; i++) { 47 document.body.insertBefore(aCacheSpan[i], oBox); 48 } 49 aCacheSpan = []; 50 } 51 for (var i = (page - 1) * perPage; i < (page - 1) * perPage + perPage; i++) { 52 console.log(aSpan[i].innerHTML); 53 oDiv = cache.getDiv(); 54 oDiv.innerHTML = aSpan[i].innerHTML; 55 aCacheSpan.push(document.body.replaceChild(oDiv, aSpan[i])); 56 } 57 } 58 } 59 </script>
五、cloneNode: 复制一个节点
用法:
someNode.clone( bool值 )
参数有两种情况:
如果为true: 代表深拷贝: 即复制当前节点和他下面的所有子节点,如果存在行间事件,也会被复制
如果为false: 代表浅拷贝:即复制当前节点,不会复制他下面的子节点
返回值:返回当前被复制的元素
1 <input type="button" value="深拷贝" id="btn1"> 2 <input type="button" value="浅拷贝" id="btn2"> 3 <ul> 4 <li>1</li> 5 <li>2</li> 6 <li>3</li> 7 <li>4</li> 8 </ul> 9 <script> 10 var oBtn1 = document.querySelector("#btn1"); 11 var oBtn2 = document.querySelector("#btn2"); 12 var oUl = document.querySelector( "ul" ); 13 oBtn1.onclick = function () { 14 var aNode = oUl.cloneNode( true ); 15 console.log( aNode ); 16 } 17 oBtn2.onclick = function () { 18 var aNode = oUl.cloneNode( false ); 19 console.log( aNode ); 20 } 21 </script>