天天看點

節點插入

對于早期的w3c浏覽器,并沒有實作ie的私有方法insertAdjacentHTML(目前已是HTML5标準),可以用appendChild模拟該方法的實作:

  

if(typeof HTMLElement !=='undefined' && !HTMLElement.prototype.insertAdjacentHTML){
            var insertAdjacentElement = function(node,position,el){
                switch (position.toLowerCase()){
                    case 'beforebegin':
                        node.parentNode.insertBefore(el,node);
                        break;
                    case 'afterbegin':
                        node.insertBefore(el,node.firstChild);
                        break;
                    case 'beforeend':
                        node.appendChild(el);
                        break;
                    case 'afterend':
                        if(node.nextSibling){
                            node.parentNode.insertBefore(el,node.nextSibling);
                        }else{
                            node.parentNode.appendChild(el);
                        }
                        break;
                }
            };
            HTMLElement.prototype.insertAdjacentHTML = function(position,html){
                var range = document.createRange(),frag,
                        parent;
                range.setStart(document.body);
                frag = range.createContextualFragment(html);
                if(this.nodeType == 3 || this.nodeType == 8){
                    parent = this.parentNode;
                    insertAdjacentElement(parent,position,frag);
                }else{
                    insertAdjacentElement(this,position,frag);
                }
            }
        }      

  使用了Range.createContextualFragment(html)方法,MDN對該方法叙述:The 

Range.createContextualFragment()

 method returns a 

DocumentFragment

by invoking the HTML fragment parsing algorithm or the XML fragment parsing algorithm with the start of the range (the parent of the

selected node) as the context node. The HTML fragment parsing algorithm is used if the range belongs to a 

Document

 whose HTMLness bit

is set. In the HTML case, if the context node would be 

html

, for historical reasons the fragment parsing algorithm is invoked with 

body

 as the context instead. 也就是說,選中節點的父節點(即Range對象的startContainer屬性)為HTML(XML)文檔片段解析算法的上下文節點。

該方法相容Chrome,Firefox,IE11,以及Opera15.對于模拟insertAdjacentHTML足夠用。當然也可使用相容性沒有問題的DocumentFragment對象。

  但是出于好奇,我用了jsperf對插入節點的各個方法進行性能分析,發現依舊是appendChild的插入方法效率最高(指的是機關時間内的操作數)。

  另外,對于innerHTML插入的易用性是不言而喻的,通常我們用一系列拼接的字元串給innerHTML指派,此時會調用js解析器,将解析的相關節點

作為該元素的子節點。這個屬性相容性沒有問題。相應的也有outerHTML屬性,這個相容性也沒有多大問題,除非你是用的是Firefox 11之前的版本。

對于outerHTML可以用innerHTML做一些相容性。

1 //對Firefox 11- 版本做相容,其不支援outerHTML屬性
 2         function getOuterHtml(){
 3             var e = document.createElement("div");
 4             e.appendChild(this);
 5             return e.innerHTML;
 6         }
 7         function setOuterHtml(){
 8             var e = document.createElement("div");
 9             var p = this.parentNode;
10             e.appendChild(this);
11             while(e.firstChild){
12                 p.insertBefore(e.firstChild,this);
13             }
14             p.removeChild(this);
15         }
16 
17         if(Object.defineProperty){
18             Object.defineProperty(Element.prototype,"outerHTML",{
19                 get: getOuterHtml,
20                 set: setOuterHtml,
21                 enumerable: false,
22                 configurable: false
23             })
24         }else{
25             Element.prototype.__defineGetter__("outerHTML",getOuterHtml);
26             Element.prototype.__defineSetter__("outerHTML",setOuterHtml);
27         }      

繼續閱讀