javascript 包裹节点 提高效率_javascript技巧_脚本之家

2019-11-26 16:07栏目:竞技宝竞猜
TAG:

规律基本是那般,如若传入的是字符串,那么让它们产生一个成分节点,然则这成分节点也能够有数不胜数层,在最内层把要卷入的成分放进。把字符串形成成分节点的办法犹如下多少个。1,createElement,IE能够连成分属性也一块儿创办,但只可以创立大器晚成层。2,innerHTML,可是供给对本来的字符串进行管理,IE与FF都有众多竟然的暗许行为,可认为你多加一点东西或少加一点东西。3,createContextualFragment,由于Opera的行为有一点点奇怪,需求选中纠正元素的职位。经印尼人的测量试验,它调换字符串成节点的频率比innerHTML高多了,也安然多了,真是强者愈强,弱者愈弱。借使是传播成分节点,须求克隆一下,要不都成为wrapAll。尽管是函数,把当下成分传进去,利用它的一些品质成立多少个包装成分。 最早的实验品(这里的wrapOuter也就是jQuery的wrap卡塔 尔(阿拉伯语:قطر‎: 复制代码 代码如下: var parseHTML = function { if{ var range = document.createRange() range.setStartAfter return range.createContextualFragment }else{ return document.createElement } } var wrapOuter = function{ var wrap = parseHTML ; target.parentNode.insertBefore; target.previousSibling.appendChild }

多年来发掘各大类库都能运用div.innerHTML=HTML片断来生成节点成分,再把它们插入到指标成分的次第地方上。那东西实际上便是insertAdjacentHTML,可是IE可恶的innerHTML把那优势变为缺点。首先innerHTML会把内部的一些地点的空域去掉,见上面运转框的结果:

打包节点 by 司徒正美

复制代码 代码如下:

对象节点

<!doctype html>
<html dir="ltr" lang="zh-CN">
    <head>
        <meta charset="utf-8" />
        <title>
            IE的innerHTML By 司徒正美
        </title>
        <script type="text/javascript">
            window.onload = function() {
                var div = document.createElement("div");
                div.innerHTML = "   <td>    <b>司徒</b>正美         </td>        "
                alert("|" + div.innerHTML + "|");
                var c = div.childNodes;
                alert("生成的节点个数  " + c.length);
                for(var i=0,n=c.length;i<n;i++){
                      alert(c[i].nodeType);
                      if(c[i].nodeType === 1){
                          alert(":: "+c[i].childNodes.length);
                      }
                }       
            }
        </script>
    </head>

[Ctrl+A 全选 注:如需引入外部Js需刷新本事实行]

    <body>
        <p id="p">
        </p>
    </body>

发觉在Opera中出了些难点,range.setStartAfter要改成大家的靶子成分才行。再者,将插入包裹成分的诀窍由insertBefore改为replaceChild,进步效率。复制代码 代码如下:var wrapOuter = function{ var wrap = html if(Object.prototype.toString.call === "[object String]"){ if{ var range=document.createRange(); range.selectNodeContents; wrap = range.createContextualFragment.firstChild; }else { wrap = document.createElement; } } target.parentNode.replaceChild; wrap.appendChild }

</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的劳作流程吧。

指标节点

复制代码 代码如下:

[Ctrl+A 全选 注:如需引进外界Js需刷新技艺施行]复制代码 代码如下: //给各类相配成分都增添一个父成分, wrap:function{//html能够是因季秋点,也得以是html片断 var _wrap = function{ var wrap; if{ if{ var range=document.createRange(); range.selectNodeContents; wrap = range.createContextualFragment.firstChild; }else { wrap = document.createElement; } }else if{ wrap = html.cloneNode } target.parentNode.replaceChild; wrap.appendChild } if{ return this.each{ _wrap(el, html.call; } return this.each{ _wrap; }, 把成立包裹元素的章程抽象出来: 复制代码 代码如下: var _parseHTML = function{ var wrap = html ; if{ var range=doc.createRange(); range.selectNodeContents; var wrap = range.createContextualFragment.firstChild; range.detach(); return wrap; }else { return dom.parseHTML; } } //给各类相配成分都加多一个父成分, wrap:function{//html能够是因商节点,也足以是html片断 var _wrap = function{ var wrap = html ; if{ wrap = dom._parseHTML; }else{ wrap = html.cloneNode } target.parentNode.replaceChild; wrap.insertBefore } if{ return this.each{ _wrap(el, html.call; } return this.each{ _wrap; }, wrapInner:function{ var _wrap = function{ var wrap = html ; if{ wrap = dom._parseHTML; }else{ wrap = html.cloneNode } target.insertBefore(wrap,target.firstChild); for(var i=1,n=target.childNodes.length;i复制代码 代码如下: var wrap = function{//html能够是因晚秋点,也足以是html片断 var _wrap = function{ var wrap = html ; if{ if{ var range=doc.createRange(); range.selectNodeContents; wrap = range.createContextualFragment.firstChild; }else{ wrap = dom.parseHTML.firstChild } }else{ wrap = html.cloneNode } target.parentNode.replaceChild; while ( wrap.firstChild && wrap.firstChild.nodeType === 1 ) { wrap = wrap.firstChild; } wrap.insertBefore } if{ return this.each{ _wrap(el, html.call; } return this.each{ _wrap; } //把每几个相配成分的子节点都用东西包裹起来 var wrapInner = function{ var _wrap = function{ var wrap = html ; if{ wrap = dom.parseHTML.firstChild }else{ wrap = html.cloneNode } target.insertBefore(wrap,target.firstChild); while ( wrap.firstChild && wrap.firstChild.nodeType === 1 ) { wrap = wrap.firstChild; } for(var i=1,n=target.childNodes.length;i复制代码 代码如下: dom.mixin{ var wrapHelper = function{ var wrap = html ; if{ if{ var range=dom.doc.createRange(); range.selectNodeContents; wrap = range.createContextualFragment.firstChild; } else{ wrap = dom.parseHTML.firstChild } }else{ wrap = html.cloneNode } var insertor = wrap; while ( insertor.firstChild && insertor.firstChild.nodeType === 1 ) { insertor = insertor.firstChild; } return [wrap,insertor] } //用三个标签包裹全体相配元素//做法:在率先个相配成分上增多三个父成分,然后把其余匹配成分都改造来此父成分中来 //wrapAll var wrapAll = function{ if ( dom.isFunction { return this.each { dom.wrapAll( html.call; } var arr = wrapHelper; var wrap = arr[0],insertor =arr[1]; this[0].parentNode.replaceChild; return this.each{ insertor.insertBefore; } //给每一种相称成分都增多叁个父成分, var wrap= function { return this.each { dom.wrapAll; } //把每二个相称成分的子节点都用东西包裹起来 var wrapInner = function{ var _wrap = function{ var arr = wrapHelper; var wrap = arr[0],insertor =arr[1]; target.insertBefore(wrap,target.firstChild); for(var i=1,n=target.childNodes.length;i

append: function() {
  //传入arguments对象,true为要对表格举行特殊管理,回调函数
  return this.domManip(arguments, true, function(elem){
    if (this.nodeType == 1)
      this.appendChild( elem );
  });
},
domManip: function( args, table, callback ) {
  if ( this[0] ) {//即使存在成分节点
    var fragment = (this[0].ownerDocument || this[0]).createDocumentFragment(),
    //注意这里是传播四个参数
    scripts = jQuery.clean( args, (this[0].ownerDocument || this[0]), fragment ),
    first = fragment.firstChild;

    if ( first )
      for ( var i = 0, l = this.length; i < l; i++ )
        callback.call( root(this[i], first), this.length > 1 || i > 0 ?
      fragment.cloneNode(true) : fragment );

    if ( scripts )
      jQuery.each( scripts, evalScript );
  }

  return this;

  function root( elem, cur ) {
    return table && jQuery.nodeName(elem, "table") && jQuery.nodeName(cur, "tr") ?
      (elem.getElementsByTagName("tbody")[0] ||
      elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
      elem;
  }
}
//elems为arguments对象,context为document对象,fragment为空的文档碎片
clean: function( elems, context, fragment ) {
  context = context || document;

  // !context.createElement fails in IE with an error but returns typeof 'object'
  if ( typeof context.createElement === "undefined" )
  //确保context为文书档案对象
    context = context.ownerDocument || context[0] && 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
  //借使文书档案对象里面唯有二个标签,如<div>
  //大家大致只怕是在外面那样调用它$(this).append("<div>")
  //那时候就径直把它在那之中的成分名抽取来,用document.createElement("div")创立后放进数组再次回到
  if ( !fragment && elems.length === 1 && typeof elems[0] === "string" ) {
    var match = /^<(w+)s*/?>$/.exec(elems[0]);
    if ( match )
      return [ context.createElement( match[1] ) ];
  }
  //利用三个div的innerHTML创设众节点
  var ret = [], scripts = [], div = context.createElement("div");
  //假使大家是在外围那样增添$(this).append("<td>表格1</td>","<td>表格1</td>","<td>表格1</td>")
  //jQuery.each按它的第二种支分方式(没有参数,有length卡塔 尔(阿拉伯语:قطر‎遍历aguments对象,callback.call( value, i, value )
  jQuery.each(elems, function(i, elem){//i为索引,elem为arguments对象里的成分
    if ( typeof elem === "number" )
      elem += '';

    if ( !elem )
      return;

    // Convert html string into DOM nodes
    if ( typeof elem === "string" ) {
      // Fix "XHTML"-style tags in all browsers
      elem = elem.replace(/(<(w+)[^>]*?)/>/g, function(all, front, tag){
        return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ?
          all :
          front + "></" + tag + ">";
      });

      // 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("<opt") &&
        [ 1, "<select multiple='multiple'>", "</select>" ] ||

        !tags.indexOf("<leg") &&
        [ 1, "<fieldset>", "</fieldset>" ] ||

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

        !tags.indexOf("<tr") &&
        [ 2, "<table><tbody>", "</tbody></table>" ] ||

        // <thead> matched above
      (!tags.indexOf("<td") || !tags.indexOf("<th")) &&
        [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ] ||

        !tags.indexOf("<col") &&
        [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ] ||

        // IE can't serialize <link> and <script> tags normally
        !jQuery.support.htmlSerialize &&//用于成立link元素
      [ 1, "div<div>", "</div>" ] ||

        [ 0, "", "" ];

      // Go to html and back, then peel off extra wrappers
      div.innerHTML = wrap[1] + elem + wrap[2];//比如"<table><tbody><tr>" +<td>表格1</td>+"</tr></tbody></table>"

      // Move to the right depth
      while ( wrap[0]-- )
        div = div.lastChild;

      //管理IE自动插入tbody,如大家使用$('<thead></thead>')创建HTML片断,它应该回到
      //'<thead></thead>',而IE会返回'<thead></thead><tbody></tbody>'
      if ( !jQuery.support.tbody ) {

        // String was a <table>, *may* have spurious <tbody>
        var hasBody = /<tbody/i.test(elem),
        tbody = !tags.indexOf("<table") && !hasBody ?
          div.firstChild && div.firstChild.childNodes :

          // String was a bare <thead> or <tfoot>
        wrap[1] == "<table>" && !hasBody ?
          div.childNodes :
          [];

        for ( var j = tbody.length - 1; j >= 0 ; --j )
        //纵然是自动插入的中间料定未有内容
          if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length )
            tbody[ j ].parentNode.removeChild( tbody[ j ] );

      }

      // IE completely kills leading whitespace when innerHTML is used
      if ( !jQuery.support.leadingWhitespace && /^s/.test( elem ) )
        div.insertBefore( context.createTextNode( elem.match(/^s*/)[0] ), div.firstChild );
     //把全体节点做成纯数组
      elem = jQuery.makeArray( div.childNodes );
    }

    if ( elem.nodeType )
      ret.push( elem );
    else
    //全并三个数组,merge方法会管理IE下object成分下未有了的param成分
      ret = jQuery.merge( ret, elem );

  });

版权声明:本文由龙竞技官网发布于竞技宝竞猜,转载请注明出处:javascript 包裹节点 提高效率_javascript技巧_脚本之家