JAvascriptラップノード

13920 ワード

jQueyを真似て、いくつかのラップノードを作成する方法を見て、jQueryの方法が非常に効果的ではないことを発見して、次は彼はまたこのいくつかの方法がどれだけ向上したかを言うことができます.原理は基本的にこのようにして、文字列が伝わると、それらを要素ノードにしますが、この要素ノードには多くの層があり、最内層で包む要素を入れることができます.文字列を要素ノードにする方法は以下のとおりです.1,createElement,IEは要素属性も一緒に作成できますが、1層しか作成できません.2,innerHTMLですが、元の文字列を処理する必要があります.IEとFFには予想外のデフォルトの行為がたくさんあります.もっと追加したり、少し追加したりすることができます.3,createContextualFragment,Operaの動作が少しおかしいので,修正要素の位置を選択する必要がある.日本人のテストを経て、文字列をノードに変換する効率はinnerHTMLよりずっと高く、安全で、本当に強者ほど強く、弱者ほど弱くなった.エレメントノードに転送する場合は、クローンを作成する必要があります.wrapAllになります.関数の場合は、現在の要素を転送し、そのプロパティの一部を使用してラップ要素を作成します.
最初の実験品(ここのwrapOuterはjQueryのwrapに相当する):


        var parseHTML = function(str) {

          if(document.createRange){

            var range = document.createRange()

            range.setStartAfter(document.body)

            return range.createContextualFragment(str)

          }else{

            return document.createElement(str)

          }

        }

        var wrapOuter = function(target,html){

          var wrap =  parseHTML(html) ;

          target.parentNode.insertBefore(wrap,target);

          target.previousSibling.appendChild(target)

        }








ラップノードby司徒正美

window.onload = function(){
var parseHTML = function(str) {
if(document.createRange){
var range = document.createRange()
range.setStartAfter(document.body)
return range.createContextualFragment(str)
}else{
return document.createElement(str)
}
}
var wrapOuter = function(target,html){
var wrap = parseHTML(html) ;
target.parentNode.insertBefore(wrap,target);
target.previousSibling.appendChild(target)
}
var a = document.getElementById("target");
wrapOuter(a,"
")
}




ターゲットノード




実行コード
Operaにに質問が出ていることに気づいたsetStartAfter(document.body)は、ターゲット要素に変更する必要があります.さらに,ラップ要素を挿入する方式をinsertBeforeからreplaceChildに変更し,効率を高めた.


        var wrapOuter = function(target,html){

          var wrap = html

          if(Object.prototype.toString.call(html) === "[object String]"){

            if(document.createRange){

              var range=document.createRange();

              range.selectNodeContents(target);

              wrap = range.createContextualFragment(html).firstChild;

            }else {

              wrap = document.createElement(str);

            }

          }

          target.parentNode.replaceChild(wrap,target);

          wrap.appendChild(target)

        }








ラップノードby司徒正美

window.onload = function(){
var wrapOuter = function(target,html){
var wrap = html
if(Object.prototype.toString.call(html) === "[object String]"){
if(document.createRange){
var range=document.createRange();
range.selectNodeContents(target);
wrap = range.createContextualFragment(html).firstChild;
}else {
wrap = document.createElement(str);
}
}
target.parentNode.replaceChild(wrap,target);
wrap.appendChild(target)
}
var a = document.getElementById("target");
wrapOuter(a,"
")
}




ターゲットノード




実行コード


        //               (    ),

        wrap:function(html){//html       ,    html  

            var _wrap = function(target,html){

                var wrap;

                if(is(html,"String")){

                    if(document.createRange){

                        var range=document.createRange();

                        range.selectNodeContents(target);

                        wrap = range.createContextualFragment(html).firstChild;

                    }else {

                        wrap = document.createElement(html);

                    }

                }else if(html.nodeType){

                    wrap = html.cloneNode(true)

                }

                target.parentNode.replaceChild(wrap,target);

                wrap.appendChild(target)

            }

            if(is(html,"Function")){

                return this.each(function(el,index){

                    _wrap(el, html.call(el,index));

                });

            }

            return this.each(function(el){

                _wrap(el,html)

            });

        

        },


ラップ要素を作成する方法を抽象化します.


         var _parseHTML = function(el,html){

            var wrap = html ;

            if(doc.createRange){

                var range=doc.createRange();

                range.selectNodeContents(el);

                var wrap = range.createContextualFragment(html).firstChild;

                range.detach();

                return wrap;

            }else {

                return  dom.parseHTML(html);

            }

        }

        //               (    ),

        wrap:function(html){//html       ,    html  

            var _wrap = function(target,html){

                var wrap = html ;

                if(!wrap.nodeType){

                    wrap = dom._parseHTML(target,html);

                }else{

                    wrap = html.cloneNode(true)

                }

                target.parentNode.replaceChild(wrap,target);

                wrap.insertBefore(target,null)

            }

            if(is(html,"Function")){

                return this.each(function(el,index){

                    _wrap(el, html.call(el,index));

                });

            }

            return this.each(function(el){

                _wrap(el,html)

            });

        

        },

        wrapInner:function(html){

            var _wrap = function(target,html){

                var wrap = html ;

                if(!wrap.nodeType){

                    wrap = dom._parseHTML(target,html);

                }else{

                    wrap = html.cloneNode(true)

                }

                target.insertBefore(wrap,target.firstChild);

                for(var i=1,n=target.childNodes.length;i<n;i++){

                    wrap.appendChild(target.childNodes[i],null)

                }

            }

            if(is(html,"Function")){

                return this.each(function(el,index){

                    _wrap(el, html.call(el,index));

                });

            }

            return this.each(function(el){

                _wrap(el,html)

            });

        },

        //             

        //  :                (  ),                   

        //wrapAll(html) wrapAll(elem)

        wrapAll:function(html){

            var wrap = html;

            if(!wrap.nodeType)

                wrap = dom._parseHTML(this[0],html);

            this[0].parentNode.replaceChild(wrap,this[0]);

            return this.each(function(el){

                wrap.insertBefore(el,null);

            });

        },


jQuery公式サイトまで見てみると、そのラップノードの方法がアップグレードされていて、毎回多くの層をラップすることができますが、私の毎回は1層しかパッケージできません.そこで私の元のparseHTMLメソッドを呼び出すことにしました.ここを参照してください.


       var wrap = function(html){//html       ,    html  

        var _wrap = function(target,html){

          var wrap = html ;

          if(!wrap.nodeType){

            if(doc.createRange){

              var range=doc.createRange();

              range.selectNodeContents(target);

              wrap = range.createContextualFragment(html).firstChild;

            }else{

              wrap = dom.parseHTML(html,null,true).firstChild

            }

          }else{

            wrap = html.cloneNode(true)

          }

          target.parentNode.replaceChild(wrap,target);

          while ( wrap.firstChild && wrap.firstChild.nodeType === 1 ) {

            wrap = wrap.firstChild;

          }

          wrap.insertBefore(target,null)

        }

        if(is(html,"Function")){

          return this.each(function(el,index){

            _wrap(el, html.call(el,index));

          });

        }

        return this.each(function(el){

          _wrap(el,html)

        });

        

      }

      //                    

      var wrapInner = function(html){

        var _wrap = function(target,html){

          var wrap = html ;

          if(!wrap.nodeType){

            wrap = dom.parseHTML(html,null,true).firstChild

          }else{

            wrap = html.cloneNode(true)

          }

          target.insertBefore(wrap,target.firstChild);

          while ( wrap.firstChild && wrap.firstChild.nodeType === 1 ) {

            wrap = wrap.firstChild;

          }

          for(var i=1,n=target.childNodes.length;i<n;i++){

            wrap.appendChild(target.childNodes[i],null)

          }

        }

        if(is(html,"Function")){

          return this.each(function(el,index){

            _wrap(el, html.call(el,index));

          });

        }

        return this.each(function(el){

          _wrap(el,html)

        });

      }

      //             

      //  :                (  ),                   

      //wrapAll(html) wrapAll(elem)

      var wrapAll = function(html){

        var wrap = html;

        if(!wrap.nodeType){

          if(doc.createRange){

            var range = doc.createRange();

            range.selectNodeContents(this[0]);

            wrap = range.createContextualFragment(html).firstChild;

          }else{

            wrap = dom.parseHTML(html,null,true).firstChild

          }

        } else{

          wrap = html.cloneNode(true)

        }

        this[0].parentNode.replaceChild(wrap,this[0]);

        while ( wrap.firstChild && wrap.firstChild.nodeType === 1 ) {

          wrap = wrap.firstChild;

        }

        return this.each(function(el){

          wrap.insertBefore(el,null);

        });

      }


多くの重複コードを発見し、抽象的に言えば、外部の人にとって、徹底的に何をしているのか分からないが、jQueryもこのように一歩一歩難解になっているに違いない.


    dom.mixin(dom[fn],(function(){

       

        var wrapHelper = function(target,html ){

            var wrap = html ;

            if(!wrap.nodeType){

                if(document.createRange){

                    var range=dom.doc.createRange();

                    range.selectNodeContents(target);

                    wrap = range.createContextualFragment(html).firstChild;

                } else{

                    wrap = dom.parseHTML(html,null,true).firstChild

                }

            }else{

                wrap = html.cloneNode(true)

            }

            var insertor = wrap;

            while ( insertor.firstChild && insertor.firstChild.nodeType === 1 ) {

                insertor = insertor.firstChild;

            }

            return [wrap,insertor]

        }

       

        //             

        //  :                (  ),                   

        //wrapAll(html) wrapAll(elem)

        var wrapAll = function(html){

            if ( dom.isFunction( html ) ) {

                return this.each(function(el,index) {

                    dom(this).wrapAll( html.call(this, index));

                });

            }

            var arr = wrapHelper(this[0],html);

            var wrap = arr[0],insertor =arr[1];

            this[0].parentNode.replaceChild(wrap,this[0]);

            return this.each(function(el){

                insertor.insertBefore(el,null);

            });

        }

      //               (    ),

        var wrap= function( html ) {

            return this.each(function() {

                dom( this ).wrapAll( html );

            });

        }

        //                    

        var wrapInner = function(html){

            var _wrap = function(target,html){

                var arr = wrapHelper(target,html);

                var wrap = arr[0],insertor =arr[1];

                target.insertBefore(wrap,target.firstChild);

                for(var i=1,n=target.childNodes.length;i<n;i++){

                    insertor.appendChild(target.childNodes[i],null)

                }

            }

            if(is(html,"Function")){

                return this.each(function(el,index){

                    _wrap(el, html.call(el,index));

                });

            }

            return this.each(function(el){

                _wrap(el,html)

            });

        }

        return {

            wrapAll:wrapAll,

            wrap:wrap,

            wrapInner:wrapInner

        }

    })());


unwrapの方法は後で話します!