Javascript package node improves efficiency

Source: Internet
Author: User

The principle is basically like this. If strings are input, convert them into an element node. However, this element node can also have many layers and put the elements to be wrapped in the innermost layer. There are several methods to convert a string into an element node.
1. createElement and IE can be created together with element attributes, but only one layer can be created.
2. innerHTML, but the original string needs to be processed. Both IE and FF have many unexpected default behaviors, so you can add more or less.
3. createContextualFragment. Because Opera has a strange behavior, you need to select and modify the position of the element. Tested by the Japanese, it is much more efficient and safer to convert strings into nodes than innerHTML. The stronger the character, the weaker the character. If you want to input an element node, You need to clone it or change it to wrapAll. If it is a function, pass the current element in and use some of its attributes to create a package element.
The original experiment (here wrapOuter is equivalent to jQuery's wrap ):
Copy codeThe Code is as follows:
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. previussibling. appendChild (target)
}

<! Doctype html> <ptml dir = "ltr" lang = "zh-CN"> <pead> <meta charset = "UTF-8"/> <meta content = "IE = 8" http -equiv = "X-UA-Compatible"/> <style type = "text/css">. wrapper {margin: 5px 5px 5px 5px; padding: 5px 5px 5px; background-color: # dfe8f6; border: 1px solid magenta ;}. inner {margin: 1em; height: 20px; background: # a9ea00 }. border {border: 2px solid red ;} </style> <title> wrapped node by situ zhengmei </title> </pead> <body id = "id10"> target node </body> </ptml>
[Ctrl + A select all Note: If you need to introduce external Js, You need to refresh it to execute]

If something goes wrong with Opera, change range. setStartAfter (document. body) to our target element. In addition, the method for inserting package elements is changed from insertBefore to replaceChild to improve efficiency.
Copy codeThe Code is as follows:
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)
}

<! Doctype html> <ptml dir = "ltr" lang = "zh-CN"> <pead> <meta charset = "UTF-8"/> <meta content = "IE = 8" http -equiv = "X-UA-Compatible"/> <style type = "text/css">. wrapper {margin: 5px 5px 5px 5px; padding: 5px 5px 5px; background-color: # dfe8f6; border: 1px solid magenta ;}. inner {margin: 1em; height: 20px; background: # a9ea00 }. border {border: 2px solid red ;} </style> <title> wrapped node by situ zhengmei </title> </pead> <body id = "id10"> target node </body> </ptml>
[Ctrl + A select all Note: If you need to introduce external Js, You need to refresh it to execute]
Copy codeThe Code is as follows:
// Add a parent element (package element) to each matching element ),
Wrap: function (html) {// html can be an element node or an html part.
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)
});
},

Abstract The method for creating a package element:
Copy codeThe Code is as follows:
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 );
}
}
// Add a parent element (package element) to each matching element ),
Wrap: function (html) {// html can be an element node or an html part.
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)
});
},
// Wrap all matching elements with a tag
// Practice: Add a parent element (Package) to the first matching element, and transfer all other matching elements to the parent element.
// 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 );
});
},

Go to the jQuery official website and check that the method of its package node has been upgraded. Many layers can be wrapped each time, while I can only package one layer at a time. So I decided to call my original parseHTML method. See here.
Copy codeThe Code is as follows:
Var wrap = function (html) {// html can be an element node or html segment
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)
});
}
// Wrap each child node with matching elements
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)
});
}
// Wrap all matching elements with a tag
// Practice: Add a parent element (Package) to the first matching element, and transfer all other matching elements to the parent element.
// 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 );
});
}

I found that there were a lot of repeated code, and I would like to abstract it again. for external users, the complete deployment of cloud, jQuery is also such a step-by-step obscure.
Copy codeThe Code is as follows:
Dom. mixin (dom [fn], (function (){
Var wrapHelper = function (target, html ){
Var wrap = html;
If (! Wrap. nodeType ){
If (document. createRange ){
Var rangew.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]
}
// Wrap all matching elements with a tag
// Practice: Add a parent element (Package) to the first matching element, and transfer all other matching elements to the parent element.
// 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 );
});
}
// Add a parent element (package element) to each matching element ),
Var wrap = function (html ){
Return this. each (function (){
Dom (this). wrapAll (html );
});
}
// Wrap each child node with matching elements
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
}
})());

The unwrap method will be used later!

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

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.