首頁 >web前端 >js教程 >深入理解javascript動態插入技術_javascript技巧

深入理解javascript動態插入技術_javascript技巧

WBOY
WBOY原創
2016-05-16 17:15:591893瀏覽

最近發現各大類別庫都能利用div.innerHTML=HTML片段來產生節點元素,再把它們插入到目標元素的各個位置上。這東西其實就是insertAdjacentHTML,但IE可惡的innerHTML把這優勢變成劣勢。首先innerHTML會把裡面的某些位置的空白去掉,請看下面運行框的結果:

複製程式碼 程式碼如下:



   
       
  HTML By 司徒正美
       
       
   

   
       


 





另一個可惡的地方是,在IE中以下元素的innerHTML是唯讀的:col、 colgroup、frameset、html、 head、style、table、tbody、 tfoot、 thead、title 與 tr。為了收拾它們,Ext刻意弄了個insertIntoTable。 insertIntoTable就是利用DOM的insertBefore與appendChild來添加,情況基本上是同jQuery。不過jQuery是完全依賴這兩個方法,Ext也使用了insertAdjacentHTML。為了提高效率,所有類別庫都不約而同地使用了文檔碎片。基本流程都是透過div.innerHTML提取出節點,然後轉移到文件碎片上,然後用insertBefore與appendChild插入節點。對於火狐,Ext也使用了createContextualFragment解析文本,直接插入其目標位置。顯然,Ext的比jQuery是快許多的。不過jQuery的插入的不單是HTML片斷,還有各種節點與jQuery物件。下面重溫一下jQuery的工作流程吧。

複製程式碼

程式碼如下:


append: function() {
  //傳入arguments對象,true為要對錶格進行特殊處理,回呼函數
  return this.domManip(arguments, true, function(elem){
    if (this.nodeType == 1)
      this.appendChild( elem );
  });
},
domManip: function( args, 3: funcs ), 3: functabled args,a) if ( this[0] ) {//如果存在元素節點
    var fragment = (this[0].ownerDocument || this[0]).createDocumentFragment(),
    //注意這裡是傳入三三三三三三三個參數
    scripts = jQuery.clean( args, (this[0].ownerDocument || this[0]), fragment ),
    first = fragment.firstChildld
    first = fragment.firstChildld
    
      for ( var i = 0, l = this.length; i         callback.call( root(this[i], first), this.||
      fragment.cloneNode(true) : fragment );

    if ( scripts )
      jQuery.each( scripts 🎜 >
  function root( elem, cur ) {
    return table && jQuery.nodeName(elem, "table") && jQuery.nodeName(cur, "tr") ?
  ")[0] ||
      elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
      elem;
  } / clean: function( elems, context, fragment ) {
  context = context || document;

  // !context.createElement fails in IEIE with an error but returns typeof 'object'
  if ( typeof context.createElement === "undefined" )
  //確保context為文件物件
    context = context.ownerDocument.ownp. context[0].ownerDocument || document;

  // If a single string is passed in and it's a single tag
  // just do a createElement and skip the rest
  // just do a createElement and skip the rest
  //我們大概可能是在外面這樣呼叫它$(this).append("
")
  //這時就直接把它裡面的元素名取出來,用document.createElement("div")創建後放進數組返回
  if ( !fragment && elems.length === 1 && typeof elems[0] === "string" ) {
    var match = /^$/.exec(elems[0]);
    if ( match )
      return [ context.createElement( match[1] ); 🎜>  }
  //利用一個div的innerHTML創建一個眾節點
  var ret = [], scripts = [], div = context.createElement("div");
  //如果我們在外面這樣加$(this).append("表格1","表格1","表格1")
  / /jQuery.each按它的第四種支分方式(沒有參數,有length)遍歷aguments對象,callback.call( value, i, value )
  jQuery.each(elems, function(i, elem){ //i為索引,elem為arguments物件裡的元素
    if ( typeof elem === "number" )
      elem = '';

     elem = '';

     elem = '';

    // Convert html string into DOM nodes
    if ( typeof elem === "string" ) {
   elem.replace(/(]*?)/>/g, function(all, front, tag){
        return tag.match(/^(abbr|br|col|img|br|col|img| input|link|meta|param|hr|area|embed)$/i) ?
         all :
        );

      // Trim whitespace, otherwise indexOf won't work as expected
      var tags = elem.replace(/^\s+/, "").substring(0, 10).toLowerCase();

      var wrap =
        // option or optgroup
        !tags.indexOf(" [ 1, "" ] ||

        !tags.indexOf(" [ 1, "
", "
" ] ||

        tags.match(/^<(thead|tbody|tfoot|colg|cap)/) &&
[ 1, "", "
" ] ||

        !tags.indexOf(" [ 2, "", "
" ] ||

        // matched above
      (!tags.indexOf(" [ 3, "", "
" ] ||

        !tags.indexOf(" [ 2, "", "
" ] ||

        // IE can't serialize and