javascript 替換節點

來源:互聯網
上載者:User

這可能是最被忽略的文檔操作之一,這都怪微軟的不作為與W3C的無能,搞到大家只知道appendChild與insertBefore。後來爆出appendChild在IE有bug,好了,以後只用insertBefore了。現在jQuery興起後,無數趕鴨子上架的javascript素人連基本API也不學了,直接上手append, preppend, before, after與replaceWith,這比較悲哀……好了,我們先來看w3c的替換節點方法吧。

replacedNode = parentNode.replaceChild(newChild, oldChild)。從公式中我們可以看出科學家與工程師亽區別,為了執行它,需要三個節點進行參與,並且返回的是被替換的元素,這不利於鏈式操作。好處是適用性廣,支援XML與HTML。

      var $ = function(id){        return document.getElementById(id)      }       var replace = function(){        var ul =  $("ul"),        lis = ul.innerHTML,        ol = document.createElement("ol");        ul.parentNode.replaceChild(ol,ul);        ol.innerHTML = lis;        replace = function(){}//只允許執行一次      }

<br /><!doctype html><br /><html lang="en"><br /> <head><br /> <meta charset="utf-8" /><br /> <meta content="IE=8" http-equiv="X-UA-Compatible"/><br /> <title>替換節點 by 司徒正美 </title><br /> <script type="text/javascript"><br /> var $ = function(id){<br /> return document.getElementById(id)<br /> }<br /> var replace = function(){<br /> var ul = $("ul"),<br /> lis = ul.innerHTML,<br /> ol = document.createElement("ol");<br /> ul.parentNode.replaceChild(ol,ul);<br /> ol.innerHTML = lis;<br /> replace = function(){}//只允許執行一次<br /> }</p><p> </script><br /> </head><br /> <body><br /> <ul id="ul" ><br /> <li>List Item 1</li><br /> <li>List Item 2</li><br /> <li>List Item 3</li><br /> <li>List Item 4</li><br /> </ul><br /> <button type="button" onclick = "replace()" >替換節點</button><br /> </body><br /></html><br />

運行代碼

oReplace = object.replaceNode(oNewNode)。微軟的私人實現,不過只支援HTML。好處是只用到兩個節點。

      var $ = function(id){        return document.getElementById(id)      }      var replace = function(){        var ul =  $("ul"),        lis = ul.innerHTML,        ol = document.createElement("ol");        ul.replaceNode(ol);        ol.innerHTML = lis;      }

<br /><!doctype html><br /><html lang="en"><br /> <head><br /> <meta charset="utf-8" /><br /> <meta content="IE=8" http-equiv="X-UA-Compatible"/><br /> <title>替換節點 by 司徒正美 </title><br /> <script type="text/javascript"><br /> var $ = function(id){<br /> return document.getElementById(id)<br /> }<br /> var replace = function(){<br /> var ul = $("ul"),<br /> lis = ul.innerHTML,<br /> ol = document.createElement("ol");<br /> ul.replaceNode(ol);<br /> ol.innerHTML = lis;<br /> }</p><p> </script><br /> </head><br /> <body><br /> <ul id="ul" ><br /> <li>List Item 1</li><br /> <li>List Item 2</li><br /> <li>List Item 3</li><br /> <li>List Item 4</li><br /> </ul><br /> <button type="button" onclick = "replace()" >替換節點</button><br /> </body><br /></html><br />

運行代碼

outerHTML方式。非常高效的方式。不用建立節點,不過缺陷也比較多。先說IE,它的XML文檔不支援這方法,在HTML中,由於col, colgroup, frameset, html, head, style, title, table, tbody, tfoot, thead, tr, td與th的innerHTML是唯讀,因此修改它們時需要用到一些技巧。html,head,title也不說了,基本上操作文檔與它不沾邊。style元素也用得少,只要是table系列的。修改它們時,找到它們的table一併修改就是。標準瀏覽器方面,XML不支援,HTML則由於已列入草案,就剩下Firefox在負隅頑抗。如果我們要替換的元素有子節點而我們又需要保留它們,這時我們又得考慮這些元素在innerHTML之後的屬性恢複問題。參見我的另一篇博文《如何區分屬性與特性》,標準瀏覽器中不用setAttribute設定的屬性,會innerHTML中會丟失。因此我們這就要規範人們要用setAttribute設定屬性(特性),不要用obj.prop這種純javascript Object方式。

      var $ = function(id){        return document.getElementById(id)      }      var replace = function(){        var ul =  $("ul");        ul.outerHTML = "<ol>"+ul.innerHTML+"</ol>"        replace = function(){}//只允許執行一次      }

<br /><!doctype html><br /><html lang="en"><br /> <head><br /> <meta charset="utf-8" /><br /> <meta content="IE=8" http-equiv="X-UA-Compatible"/><br /> <title>替換節點 by 司徒正美 </title><br /> <script type="text/javascript"><br /> var $ = function(id){<br /> return document.getElementById(id)<br /> }<br /> var replace = function(){<br /> var ul = $("ul");<br /> ul.outerHTML = "<ol>"+ul.innerHTML+"</ol>"<br /> replace = function(){}//只允許執行一次<br /> }<br /> </script><br /> </head><br /> <body><br /> <ul id="ul" ><br /> <li>List Item 1</li><br /> <li>List Item 2</li><br /> <li>List Item 3</li><br /> <li>List Item 4</li><br /> </ul><br /> <button type="button" onclick = "replace()" >替換節點</button><br /> </body><br /></html><br />

運行代碼

下面是示範outerHTML在IE表格中遭遇滑鐵盧。

      var replace = function(){        var td =  $("td");        td.outerHTML = ""+td.innerHTML+""        replace = function(){}//只允許執行一次      }

<br /><!doctype html><br /><html lang="en"><br /> <head><br /> <meta charset="utf-8" /><br /> <meta content="IE=8" http-equiv="X-UA-Compatible"/><br /> <title>替換節點 by 司徒正美 </title><br /> <script type="text/javascript"><br /> var $ = function(id){<br /> return document.getElementById(id)<br /> }<br /> var replace = function(){<br /> var td = $("td");<br /> td.outerHTML = "<th>"+td.innerHTML+"</th>"<br /> replace = function(){}//只允許執行一次<br /> }<br /> </script><br /> </head><br /> <body><br /> <table border="1"><br /> <tr><td id="td">Ruby Louvre</td></tr><br /> </table><br /> <button type="button" onclick = "replace()" >替換節點</button><br /> </body><br /></html><br />

運行代碼

修正方法:

      var $ = function(id){        return document.getElementById(id)      }      var getTable = function(el){        while(el = el.parentNode){          if(el.tagName.toLowerCase() === "table")            return el        }      }      var tableObject = {        "col":1,        "colgroup":1,        "tbody":1,        "tfoot":1,        "thead":1,        "tr":1,        "td":1,        "th":1      }//frameset是HTML5要廢棄的元素,不管, html, head, title與style出現機率效少,也不管      var replace = function(){        var td =  $("td");        if(!+"\v1" && tableObject[td.tagName.toLowerCase()]){          var table = getTable(td);          table.outerHTML = table.outerHTML.replace(td.outerHTML,""+td.innerHTML+"")        }else{          td.outerHTML = ""+td.innerHTML+""        }        replace = function(){}//只允許執行一次      }

<br /><!doctype html><br /><html lang="en"><br /> <head><br /> <meta charset="utf-8" /><br /> <meta content="IE=8" http-equiv="X-UA-Compatible"/><br /> <title>替換節點 by 司徒正美 </title><br /> <script type="text/javascript"><br /> var $ = function(id){<br /> return document.getElementById(id)<br /> }<br /> var getTable = function(el){<br /> while(el = el.parentNode){<br /> if(el.tagName.toLowerCase() === "table")<br /> return el<br /> }<br /> }<br /> var tableObject = {<br /> "col":1,<br /> "colgroup":1,<br /> "tbody":1,<br /> "tfoot":1,<br /> "thead":1,<br /> "tr":1,<br /> "td":1,<br /> "th":1<br /> }//frameset是HTML5要廢棄的元素,不管, html, head, title與style出現機率效少,也不管<br /> var replace = function(){<br /> var td = $("td");<br /> if(!+"\v1" && tableObject[td.tagName.toLowerCase()]){<br /> var table = getTable(td);<br /> table.outerHTML = table.outerHTML.replace(td.outerHTML,"<th>"+td.innerHTML+"</th>")<br /> }else{<br /> td.outerHTML = "<td>"+td.innerHTML+"</td>"<br /> }<br /> replace = function(){}//只允許執行一次<br /> }</p><p> </script><br /> </head><br /> <body><br /> <table border="1"><br /> <tr><th id="td">Ruby Louvre</th></tr><br /> </table><br /> <button type="button" onclick = "replace()" >替換節點</button><br /> </body><br /></html><br />

運行代碼

總結:以上例子的需求比較變態,都是限定要替換某一節點卻不替換它的子節點,如果不考慮其子節點,就方便多。為了效率,我們建議IE用replaceNode,Firefox用replaceChild,其他標準瀏覽器用outerHTML,我們可以把它們封裝為一個函數。至於為什麼不用innerHTML,好問題,因為要替換的節點可能存在兄弟節點。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.