Home  >  Article  >  Web Front-end  >  In-depth understanding of javascript dynamic insertion technology_javascript skills

In-depth understanding of javascript dynamic insertion technology_javascript skills

WBOY
WBOYOriginal
2016-05-16 17:15:591847browse

Recently, I found that all major libraries can use div.innerHTML=HTML fragments to generate node elements, and then insert them into various positions of the target element. This thing is actually insertAdjacentHTML, but IE's abominable innerHTML turns this advantage into a disadvantage. First, innerHTML will remove the blank spaces in certain positions. See the results of the run box below:

Copy code The code is as follows:






<br> IE's InnerHtml By Situ Zhengmei <br> & lt;/Title & GT; <br> & LT; Script Type = "Text/Javascript" & GT; <br> Window.onload = Function () {<br> VAR DIV = D = D = D = D ocument.createelement ( "div");<br> div.innerHTML = " <td> <b>Situ</b>正美 " "<br> " alert("|" div.innerHTML "|"); <br>          var c = div.childNodes; <br> alert(c[i].nodeType);<br> if(c[i].nodeType === 1){<br> alert(":: " c[i] .childNodes.length);<br>                                                                                      ><br>                                                                            <br>                                                                                 <br></html><br> <br><br><br> <br>Another nasty thing is that the innerHTML of the following elements is read-only in IE: col, colgroup, frameset, html, head, style, table, tbody, tfoot, thead, title and tr. In order to clean them up, Ext specially made an insertIntoTable. insertIntoTable is added using DOM's insertBefore and appendChild. The situation is basically the same as jQuery. However, jQuery completely relies on these two methods, and Ext also uses insertAdjacentHTML. In order to improve efficiency, all class libraries use document fragmentation invariably. The basic process is to extract nodes through div.innerHTML, then transfer them to document fragments, and then use insertBefore and appendChild to insert nodes. For Firefox, Ext also uses createContextualFragment to parse the text and insert it directly into its target location. Obviously, Ext is much faster than jQuery. However, jQuery inserts not only HTML fragments, but also various nodes and jQuery objects. Let’s review the jQuery workflow. <br> <br><br><p></p>Copy code<p></p> </div> The code is as follows:<p></p> <div class="codebody" id="code51724"> <br>append: function() { <br> //Pass in the arguments object, true means special processing of the table, callback function <br> return this.domManip(arguments, true, function(elem){ <br> if (this.nodeType == 1) <br> this.appendChild( elem ); <br> }); <br>}, <br>domManip: function( args, table, callback ) { <br> if ( this[0] ) {//If there is an element node <br> var fragment = (this[0].ownerDocument || this[0]).createDocumentFragment(), <br> //Note that three are passed in here parameters <br> scripts = jQuery.clean( args, (this[0].ownerDocument || this[0]), fragment ), <br> first = fragment.firstChild; <br><br> if ( first ) <br> for ( var i = 0, l = this.length; i < l; i ) <BR> callback.call( root(this[i], first), this.length > 1 || i > ; 0 ? <br> fragment.cloneNode(true) : fragment ); <br><br> if ( scripts ) <br> jQuery.each( scripts, evalScript ); <br> } <br><br> return this ; <br><br> function root( elem, cur ) { <br> return table && jQuery.nodeName(elem, "table") && jQuery.nodeName(cur, "tr") ? <br> (elem.getElementsByTagName ("tbody")[0] || <br> elem.appendChild(elem.ownerDocument.createElement("tbody"))) : <br> elem; <br> } <br>} <br>//elems are arguments object, context is the document object, and fragment is the empty document fragment <br>clean: function( elems, context, fragment ) { <br> context = context || document; <br><br> // !context.createElement fails in IE with an error but returns typeof 'object' <br> if ( typeof context.createElement === "undefined" ) <br> //Make sure context is a document object<br> context = context.ownerDocument || context[ 0] && context[0].ownerDocument || document; <br><br> // If a single string is passed in and it's a single tag <br> // just do a createElement and skip the rest <br> / /If there is only one tag in the document object, such as <div> <br> //We may call it like this from outside $(this).append("<div>") <br> //At this time Directly take out the element name inside it, create it with document.createElement("div") and put it into the array to return <br> if ( !fragment && elems.length === 1 && typeof elems[0] === "string " ) { <br> var match = /^<(w )s*/?>$/.exec(elems[0]); <br> if ( match ) <br> return [ context.createElement( match [1] ) ]; <br> } <br> //Use the innerHTML of a div to create nodes <br> var ret = [], scripts = [], div = context.createElement("div"); <br> //If we add $(this).append("<td>Table 1</td>", "<td>Table 1</td>", "<td>Table 1< ;/td>") <br> //jQuery.each traverses the agents object according to its fourth branching method (no parameters, length), callback.call( value, i, value ) <br> jQuery.each (elems, function(i, elem){//i is the index, elem is the element in the arguments object <br> if ( typeof elem === "number" ) <br> elem = ''; <br><br> if ( !elem ) <br> return; <br><br> // Convert html string into DOM nodes <br> if ( typeof elem === "string" ) { <br> // Fix "XHTML"- style tags in all browsers <br> elem = elem.replace(/(<(w )[^>]*?)/>/g, function(all, front, tag){ <br> return tag. match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ? >"; <br> }); <br><br>      // Trim whitespace, otherwise indexOf won't work as expected <br>      var tags = elem.replace(/^\s+/, "").substring(0, 10).toLowerCase(); <br><br>      var wrap = <br>        // option or optgroup <br>        !tags.indexOf("<opt") && <BR> [ 1, "<select multiple='multiple'>", "</select>" ] || <br><br>        !tags.indexOf("<leg") && <BR> [ 1, "<fieldset>", "</fieldset>" ] || <br><br>        tags.match(/^<(thead|tbody|tfoot|colg|cap)/) && <BR> [ 1, "<table>", "</table>" ] || <br><br>        !tags.indexOf("<tr") && <BR> [ 2, "<table><tbody>", "</tbody></table>" ] || <br><br>        // <thead> matched above <br>      (!tags.indexOf("<td") || !tags.indexOf("<th")) && <BR> [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ] || <br><br>        !tags.indexOf("<col") && <BR> [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ] || <br><br>        // IE can't serialize <link> and <script> tags normally <br>        !jQuery.support.htmlSerialize &&//用于创建link元素 <br>      [ 1, "div<div>", "</div>" ] || <br><br>                                                                                                           ] elem wrap[2];//For example "<table><tbody><tr>" <td>Table 1</td> "</tr></tbody></table> " <br><br> // Move to the right depth <br> while ( wrap[0]-- ) <br> div = div.lastChild; <br><br> // Process IE to automatically insert tbody, such as We use $('<thead></thead>') to create an HTML fragment, which should return <br> //'<thead></thead>', while IE will return '<thead>< ;/thead><tbody></tbody>' <br> if ( !jQuery.support.tbody ) { <br><br> // String was a <table>, *may* have spurious < tbody> <br> var hasBody = /<tbody/i.test(elem), <br> tbody = !tags.indexOf("<table") && !hasBody ? <br> div.firstChild && div.firstChild .childNodes : <br><br> // String was a bare <thead> or <tfoot> <br> wrap[1] == "<table>" && !hasBody ? <br> div.childNodes : <br> []; <br> for (var j = tBody.length -1; j & gt; = 0; --j) <br> // If it is automatically inserted, there must be no content <br> if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) <br>                   tbody[ j ].parentNode.removeChild( tbody[ j ] ); <br><br> } <br><br> // IE completely kills leading whitespace when innerHTML is used <br> if ( !jQuery.support.leadingWhitespace && /^s/.test( elem ) ) <br> div.insertBefore( context.createTextNode ( elem.match(/^s*/)[0] ), div.firstChild ); <br> //Make all nodes into pure arrays<br> elem = jQuery.makeArray( div.childNodes ); <br> } <br><br> if ( elem.nodeType ) <br> ret.push( elem ); <br> else<br> // Merge the two arrays, the merge method will handle the disappearance of the object element under IE param element <br> ret = jQuery.merge( ret, elem ); <br><br> }); <br><br> if ( fragment ) { <br> for ( var i = 0; ret[i] ; i ) { <br> //If the childNodes of the first layer have script element nodes, use scripts to collect them for later dynamic execution using globalEval <br> if ( jQuery.nodeName( ret[i], " script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) { <br> scripts.push( ret[i].parentNode ? ret [i].parentNode.removeChild( ret[i] ) : ret[i] ); <br>                                                                                                                                                                                                   . nodeType === 1 ) <br> ret.splice.apply( ret, [i 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))) ); <br> fragment. appendChild( ret[i] ); <br> } <br> } <br><br> return scripts;//Since dynamic insertion passes in three parameters, <br> is returned here } <br><br> return ret; <br>}, <br> <br><br> <p><img src="http://files.jb51.net/file_images/article/201311/20131112145628668.jpg" alt="In-depth understanding of javascript dynamic insertion technology_javascript skills" ></p> <p>It’s so complicated that it makes me cry! However, jQuery's implementation is not very clever. It uses clean to convert all inserted things into node collections, then puts them into a document fragment, and then uses appendChild and insertBefore to insert them. Today, except for Firefox, other browsers support the insertAdjactentXXX family, so you should make good use of these native APIs. The following is the DomHelper method implemented by Ext using insertAdjactentHTML and other methods. The data given by the official website: </p> <p><img src="http://files.jb51.net/file_images/article/201311/20131112145751246.jpg" alt="In-depth understanding of javascript dynamic insertion technology_javascript skills" ></p> <p>This data is a bit old, and the latest 3.03 has long solved the criticism of inserting content into IE tables (the innerHTML of table, tbody, tr, etc. are all read-only, and methods such as insertAdjactentHTML and pasteHTML cannot modify their content. You need to use The slow, standard DOM approach will do, and this is where early versions of Ext failed). It can be seen that after combining insertAdjactentHTML and document fragmentation, the speed of inserting nodes in IE6 has also been incredibly improved, almost approaching that of Firefox. Based on it, Ext developed four branch methods insertBefore, insertAfter, insertFirst, and append, which correspond to jQuery's before, after, prepend, and append respectively. However, jQuery also cleverly swapped these methods with the caller and the incoming parameters, deriving the insertBefore, insertAfter, prependTo, and appendTo methods. But in any case, jQuery’s one-size-fits-all approach is hard to disagree with. The following is a version of the insertAdjactentXXX family implemented in Firefox: </p> <p></p> <div class="codetitle"> <span><a style="CURSOR: pointer" data="29698" class="copybut" id="copybut29698" onclick="doCopy('code29698')"><u>Copy code</u></a></span> The code is as follows:</div> <div class="codebody" id="code29698"> <br>(function() { <br> if ('HTMLElement ' in this) { <br> If('insertAdjacentHTML' in HTMLElement.prototype) { <br> return<br> } <br> } else { <br> return<br> } <br><br> function insert( w, n) { <br> switch(w.toUpperCase()) { <br> case 'BEFOREEND' : <br> this.appendChild(n) <br> break<br> case 'BEFOREBEGIN' : <br> this .parentNode.insertBefore(n, this) <br> break<br> case 'AFTERBEGIN' : <br> this.insertBefore(n, this.childNodes[0]) <br> break<br> case ' AFTEREND' : <br> this.parentNode.insertBefore(n, this.nextSibling) <br> break<br> } <br> } <br><br> function insertAdjacentText(w, t) { insert.call(this, w , document.createTextNode(t || '')) <br> } <br><br> function insertAdjacentHTML(w, h) { <br> var r = document.createRange() <br> r.selectNode(this) <br> insert.call(this, w, r.createContextualFragment(h)) <br> } <br><br> function insertAdjacentElement(w, n) { <br> insert.call(this, w, n) <br> return n <br> } <br><br> HTMLElement.prototype.insertAdjacentText = insertAdjacentText <br> HTMLElement.prototype.insertAdjacentHTML = insertAdjacentHTML <br> HTMLElement.prototype.insertAdjacentElement = insertAdjacent Element <br>})() <br> <p></p> </div> We can use it to design a faster and more reasonable dynamic insertion method. Here are some of my implementations: <p> </p> <p></p> <div class="codetitle"> <span><a style="CURSOR: pointer" data="69219" class="copybut" id="copybut69219" onclick="doCopy('code69219')">Copy code<u></u></a> The code is as follows:</span><div class="codebody" id="code69219"> <br>//Four insertion methods, corresponding to the four insertion positions of insertAdjactentHTML, the names are based on jQuery's <br>//stuff can be strings, various nodes or dom objects (an array-like object, convenient Chain operation! ) <br>//The code is simpler and more beautiful than jQuery’s implementation! <br> append:function(stuff){ <br> return dom.batch(this,function(el){ <br> dom.insert(el,stuff,"beforeEnd"); <br> }); <br> }, <br> prepend:function(stuff){ <br> return dom.batch(this,function(el){ <br> dom.insert(el,stuff,"afterBegin"); <br> }); <br> }, <br> before:function(stuff){ <br> return dom.batch(this,function(el){ <br> dom.insert(el,stuff,"beforeBegin"); <br> }) ; <br> }, <br> after:function(stuff){ <br> return dom.batch(this,function(el){ <br> dom.insert(el,stuff,"afterEnd"); <br> }); <br> } <p></p> </div> <p>They all call two static methods, batch and insert. Since the DOM object is an array-like object, I followed the example of jQuery and implemented several important iterators for it, such as forEach, map and filter. A dom object contains multiple DOM elements, and we can use forEach to traverse them and execute the callback methods in them. </p> <p></p> <div class="codetitle"> <span><a style="CURSOR: pointer" data="50656" class="copybut" id="copybut50656" onclick="doCopy('code50656')"><u>Copy code</u></a></span> The code is as follows:</div> <div class="codebody" id="code50656"> <br>batch:function(els,callback){ <br> els.forEach(callback); <br> return els;//chain operation<br>},<br> </div> <p>The insert method performs the corresponding functions of jQuery's domManip method (dojo uses the place method), but the insert method processes one element node at a time, unlike jQuery which processes a group of element nodes. Cluster processing has been separated from the batch method above. </p> <p></p> <div class="codetitle"> <span><a style="CURSOR: pointer" data="32903" class="copybut" id="copybut32903" onclick="doCopy('code32903')"><u>Copy code</u></a></span> The code is as follows:</div> <div class="codebody" id="code32903"> <br>insert : function(el,stuff,where){ <br> //Define two global things and provide internal method calls<br> var doc = el.ownerDocument || dom.doc, <br> fragment = doc.createDocumentFragment(); <br> if(stuff.version){//If it is a dom object, move the element nodes inside it to the document fragment <br> stuff.forEach(function(el){ <br>          fragment.appendChild(el); ,where){ <br> switch (where){ <br> case 'beforeBegin': <br> el.parentNode.insertBefore(node,el) <br> break; <br> case 'afterBegin': <br> el .srtBeFore (node, el.firstChild); <br> Break; <br> Case 'BeForend': <br> El.appendingChild (node); <br> Break; (el.nextSibling) el.parentNode.insertBefore(node,el.nextSibling); <br> else el.parentNode.appendChild(node); <br> break; <br> } <br> }; <br> // For Firefox to call <br> dom._insertAdjacentHTML = function(el,htmlStr,where){ <br> var range = doc.createRange(); <br> switch (where) { <br> case "beforeBegin"://before <br>              range.setStartBefore(el); >              range.collapse(true); <br>                break ; <br> case "beforeEnd"://append <br> range.selectNodeContents(el); <br> range.collapse(false); <br> break; case "afterEnd"://prepend <br>               range.setStartAfter(el);                                                                ertAdjacentElement(el,parsedHTML,where); <br> }; <br> // The innerHTML of the following elements is read-only in IE. Calling insertAdjacentElement to insert will cause an error <br> // col, colgroup, frameset, html, head, style, title, table, tbody, tfoot, thead, and tr; <br> dom._insertAdjacentIEFix = function(el,htmlStr,where){ <br> var parsedHTML = dom.parseHTML(htmlStr,fragment); 🎜> }; <br> //If it is a node, make a copy<br> stuff = stuff.nodeType ? stuff.cloneNode(true) : stuff; <br> if (el.insertAdjacentHTML) {//ie, chrome, Both opera and safari have implemented insertAdjacentXXX family <br> try{//Suitable for opera, safari, chrome and IE <br> el['insertAdjacent' (stuff.nodeType ? 'Element':'HTML')](where, stuff); <br> }catch(e){ <br>                                                                               using dom._insertAdjacentIEFix(el,stuff,where);      <br> }else{ <br> } else{ //Firefox only<br> dom['_insertAdjacent' (stuff.nodeType ? 'Element':'HTML')](el,stuff,where); <br> } <br> } <br> <br><br><br> The insert method uses some rare methods of the W3C DOM Range object in implementing the Firefox insertion operation. For details, please check the Firefox official website. The following implementation converts strings into nodes, using the great method of innerHTML. Prototype.js calls it _getContentFromAnonymousElement, but there are many problems, dojo calls it _toDom, mootools' Element.Properties.html, jQuery's clean. Ext does not have this thing, it only supports the insertAdjacentHTML method of passing in HTML fragments, and does not support insertAdjacentElement of passing in element nodes. But sometimes, we need to insert text nodes (not wrapped in element nodes), then we need to use document fragments as containers, and the insert method appears. <p> </p> </div> <p></p> <p>Copy code</p> <div class="codetitle"><span><a style="CURSOR: pointer" data="59606" class="copybut" id="copybut59606" onclick="doCopy('code59606')"> The code is as follows:<u><div class="codebody" id="code59606"> <br>parseHTML: function(htmlStr, fragment){ <br> var div = dom.doc.createElement("div"), <br> reSingleTag = /^<(w )s*/?> $/;//Match a single tag, such as <li> <br> htmlStr = ''; <br> if(reSingleTag.test(htmlStr)){//If str is a single tag <br> return [dom.doc .createElement(RegExp.$1)] <br> } <br> var tagWrap = { <br> option: ["select"], <br> optgroup: ["select"], <br> tbody: ["table" ], <br> thead: ["table"], <br> tfoot: ["table"], <br> tr: ["table", "tbody"], <br> td: ["table", " tbody", "tr"], <br> th: ["table", "thead", "tr"], <br> legend: ["fieldset"], <br> caption: ["table"], <br> colgroup: ["table"], <br> col: ["table", "colgroup"], <br> li: ["ul"], <br> link:["div"] <br> } ; <br> for(var param in tagWrap){ <br> var tw = tagWrap[param]; <br> switch (param) { <br> case "option":tw.pre = '<select multiple=" multiple">'; break; <br> "<" case "link": tw.pre = 'fixbug<div>'; break; <br> "<" tw.join(">< ;") ">"; <br>       } <br>       tw.post = "</" tw.reverse().join("></") ">"; <br>                 🎜> var reMultiTag = /<s*([w:] )/,//Match a pair of tags or multiple tags, such as <li></li>,li <br> match = htmlStr.match( reMultiTag), <br> tag = match ? match[1].toLowerCase() : "";//Resolved as <li,li <BR> if(match && tagWrap[tag]){ <BR> var wrap = tagWrap[tag]; <BR> div.innerHTML = wrap.pre htmlStr wrap.post; <BR> n = wrap.length; <BR> while(--n >= 0)//Return the content we have added <br> div = div.lastChild; <br> }else{ <br> div.innerHTML = htmlStr; <br> } <br> // Process IE to automatically insert tbody, for example, we use dom.parseHTML('<thead> ;</thead>') converts the HTML fragment, it should return <br> //'<thead></thead>', while IE will return '<thead></thead><tbody> </tbody>' <br> //That is, return div.children.length will return 1 in a standard browser, and IE will return 2 <br> if(dom.feature.autoInsertTbody && !!tagWrap[tag] ){ <br> var ownInsert = tagWrap[tag].join('').indexOf("tbody") !== -1,//We inserted <br> tbody = div.getElementsByTagName("tbody"), <br> autoInsert = tbody.length > 0;//<br> inserted by IE if(!ownInsert && autoInsert){ <br> for(var i=0,n=tbody.length;i<n;i ) { <BR>                if(!tbody[i].                                                                                                                                    🎜> }  <BR> }<BR> if (dom.feature.autoRemoveBlank && /^s/.test(htmlStr) ) <BR> div.insertBefore( dom.doc.createTextNode(htmlStr.match(/^s*/)[0] ), div .firstChild ); <BR> if (fragment) { <BR> var firstChild; <BR> while((firstChild = div.firstChild)){ // Transfer the nodes on the div to the document fragment! <BR>            fragment.appendChild(firstChild); <BR><BR><BR> <BR> Well, that’s basically it. It runs much faster than jQuery, and the code implementation is pretty elegant. At least it’s not as messy as jQuery. jQuery also has four reverse methods. The following is the implementation of jQuery: <BR> </P><P></div></P><P>Copy code</P><P><div class="codetitle"> The code is as follows:<span><a style="CURSOR: pointer" data="79496" class="copybut" id="copybut79496" onclick="doCopy('code79496')"><U>jQuery.each({ </U> appendTo: "append ", </a> prependTo: "prepend", </span> insertBefore: "before", </div> insertAfter: "after", <div class="codebody" id="code79496"> replaceAll: "replaceWith"<BR>}, function(name, original){ <BR> jQuery.fn[ name ] = function( selector ) {//Insert (html, element node, jQuery object) <BR> var ret = [], insert = jQuery( selector );//Convert insert into jQuery Object <BR> for ( var i = 0, l = insert.length; i < l; i ) { <BR> var elems = (i > 0 ? this.clone(true) : this).get() ; <br>              jQuery.fn[ original].apply( jQuery(insert[i]), elems);//Call four implemented insertion methods <br>                                                                                                                            <br>         return this.pushStack( ret, name, selector);//Since the chain operation code is not separated, you need to implement it yourself <br><br><br> <br>My implementation: <br> <br><br><br><br>Copy code<p></p> </div> The code is as follows:</u><p></p> <p>dom.each({ </p> <div class="codetitle"> appendTo: 'append ', <span> prependTo: 'prepend', <a style="CURSOR: pointer" data="46384" class="copybut" id="copybut46384" onclick="doCopy('code46384')"> insertBefore: 'before', <u> insertAfter: 'after'</u>},function(method,name){ </a> dom.prototype[name] = function(stuff){ </span>         return dom(stuff)[method](this); </div> <div class="codebody" id="code46384"> <br> <br>The general code is given, so everyone can choose what they need. <br> </div></a></span></div> </div> </div></div><div class="nphpQianMsg"><div class="clear"></div></div><div class="nphpQianSheng"><span>Statement:</span><div>The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn</div></div></div><div class="nphpSytBox"><span>Previous article:<a class="dBlack" title="JS code to add emphasis to text_javascript skills" href="http://m.php.cn/faq/15528.html">JS code to add emphasis to text_javascript skills</a></span><span>Next article:<a class="dBlack" title="JS code to add emphasis to text_javascript skills" href="http://m.php.cn/faq/15530.html">JS code to add emphasis to text_javascript skills</a></span></div><div class="nphpSytBox2"><div class="nphpZbktTitle"><h2>Related articles</h2><em><a href="http://m.php.cn/article.html" class="bBlack"><i>See more</i><b></b></a></em><div class="clear"></div></div><ins class="adsbygoogle" style="display:block" data-ad-format="fluid" data-ad-layout-key="-6t+ed+2i-1n-4w" data-ad-client="ca-pub-5902227090019525" data-ad-slot="8966999616"></ins><script> (adsbygoogle = window.adsbygoogle || []).push({}); </script><ul class="nphpXgwzList"><li><b></b><a href="http://m.php.cn/faq/1609.html" title="An in-depth analysis of the Bootstrap list group component" class="aBlack">An in-depth analysis of the Bootstrap list group component</a><div class="clear"></div></li><li><b></b><a href="http://m.php.cn/faq/1640.html" title="Detailed explanation of JavaScript function currying" class="aBlack">Detailed explanation of JavaScript function currying</a><div class="clear"></div></li><li><b></b><a href="http://m.php.cn/faq/1949.html" title="Complete example of JS password generation and strength detection (with demo source code download)" class="aBlack">Complete example of JS password generation and strength detection (with demo source code download)</a><div class="clear"></div></li><li><b></b><a href="http://m.php.cn/faq/2248.html" title="Angularjs integrates WeChat UI (weui)" class="aBlack">Angularjs integrates WeChat UI (weui)</a><div class="clear"></div></li><li><b></b><a href="http://m.php.cn/faq/2351.html" title="How to quickly switch between Traditional Chinese and Simplified Chinese with JavaScript and the trick for websites to support switching between Simplified and Traditional Chinese_javascript skills" class="aBlack">How to quickly switch between Traditional Chinese and Simplified Chinese with JavaScript and the trick for websites to support switching between Simplified and Traditional Chinese_javascript skills</a><div class="clear"></div></li></ul></div></div><ins class="adsbygoogle" style="display:block" data-ad-format="autorelaxed" data-ad-client="ca-pub-5902227090019525" data-ad-slot="5027754603"></ins><script> (adsbygoogle = window.adsbygoogle || []).push({}); </script><div class="nphpFoot"><div class="nphpFootBg"><ul class="nphpFootMenu"><li><a href="http://m.php.cn/"><b class="icon1"></b><p>Home</p></a></li><li><a href="http://m.php.cn/course.html"><b class="icon2"></b><p>Course</p></a></li><li><a href="http://m.php.cn/wenda.html"><b class="icon4"></b><p>Q&A</p></a></li><li><a href="http://m.php.cn/login"><b class="icon5"></b><p>My</p></a></li><div class="clear"></div></ul></div></div><div class="nphpYouBox" style="display: none;"><div class="nphpYouBg"><div class="nphpYouTitle"><span onclick="$('.nphpYouBox').hide()"></span><a href="http://m.php.cn/"></a><div class="clear"></div></div><ul class="nphpYouList"><li><a href="http://m.php.cn/"><b class="icon1"></b><span>Home</span><div class="clear"></div></a></li><li><a href="http://m.php.cn/course.html"><b class="icon2"></b><span>Course</span><div class="clear"></div></a></li><li><a href="http://m.php.cn/article.html"><b class="icon3"></b><span>Article</span><div class="clear"></div></a></li><li><a href="http://m.php.cn/wenda.html"><b class="icon4"></b><span>Q&A</span><div class="clear"></div></a></li><li><a href="http://m.php.cn/dic.html"><b class="icon6"></b><span>Dictionary</span><div class="clear"></div></a></li><li><a href="http://m.php.cn/course/type/99.html"><b class="icon7"></b><span>Manual</span><div class="clear"></div></a></li><li><a href="http://m.php.cn/xiazai/"><b class="icon8"></b><span>Download</span><div class="clear"></div></a></li><li><a href="http://m.php.cn/faq/zt" title="Topic"><b class="icon12"></b><span>Topic</span><div class="clear"></div></a></li><div class="clear"></div></ul></div></div><div class="nphpDing" style="display: none;"><div class="nphpDinglogo"><a href="http://m.php.cn/"></a></div><div class="nphpNavIn1"><div class="swiper-container nphpNavSwiper1"><div class="swiper-wrapper"><div class="swiper-slide"><a href="http://m.php.cn/" >Home</a></div><div class="swiper-slide"><a href="http://m.php.cn/article.html" class="hover">Article</a></div><div class="swiper-slide"><a href="http://m.php.cn/wenda.html" >Q&A</a></div><div class="swiper-slide"><a href="http://m.php.cn/course.html" >Course</a></div><div class="swiper-slide"><a href="http://m.php.cn/faq/zt" >Topic</a></div><div class="swiper-slide"><a href="http://m.php.cn/xiazai" >Download</a></div><div class="swiper-slide"><a href="http://m.php.cn/game" >Game</a></div><div class="swiper-slide"><a href="http://m.php.cn/dic.html" >Dictionary</a></div><div class="clear"></div></div></div><div class="langadivs" ><a href="javascript:;" class="bg4 bglanguage"></a><div class="langadiv" ><a onclick="javascript:setlang('zh-cn');" class="language course-right-orders chooselan " href="javascript:;"><span>简体中文</span><span>(ZH-CN)</span></a><a onclick="javascript:;" class="language course-right-orders chooselan chooselanguage" href="javascript:;"><span>English</span><span>(EN)</span></a><a onclick="javascript:setlang('zh-tw');" class="language course-right-orders chooselan " href="javascript:;"><span>繁体中文</span><span>(ZH-TW)</span></a><a onclick="javascript:setlang('ja');" class="language course-right-orders chooselan " href="javascript:;"><span>日本語</span><span>(JA)</span></a><a onclick="javascript:setlang('ko');" class="language course-right-orders chooselan " href="javascript:;"><span>한국어</span><span>(KO)</span></a><a onclick="javascript:setlang('ms');" class="language course-right-orders chooselan " href="javascript:;"><span>Melayu</span><span>(MS)</span></a><a onclick="javascript:setlang('fr');" class="language course-right-orders chooselan " href="javascript:;"><span>Français</span><span>(FR)</span></a><a onclick="javascript:setlang('de');" class="language course-right-orders chooselan " href="javascript:;"><span>Deutsch</span><span>(DE)</span></a></div></div><script> var swiper = new Swiper('.nphpNavSwiper1', { slidesPerView : 'auto', observer: true,//修改swiper自己或子元素时,自动初始化swiper observeParents: true,//修改swiper的父元素时,自动初始化swiper }); </script></div></div><!--顶部导航 end--><script>isLogin = 0;</script><script type="text/javascript" src="/static/layui/layui.js"></script><script type="text/javascript" src="/static/js/global.js?4.9.47"></script></div><script src="https://vdse.bdstatic.com//search-video.v1.min.js"></script><link rel='stylesheet' id='_main-css' href='/static/css/viewer.min.css' type='text/css' media='all'/><script type='text/javascript' src='/static/js/viewer.min.js?1'></script><script type='text/javascript' src='/static/js/jquery-viewer.min.js'></script><script>jQuery.fn.wait = function (func, times, interval) { var _times = times || -1, //100次 _interval = interval || 20, //20毫秒每次 _self = this, _selector = this.selector, //选择器 _iIntervalID; //定时器id if( this.length ){ //如果已经获取到了,就直接执行函数 func && func.call(this); } else { _iIntervalID = setInterval(function() { if(!_times) { //是0就退出 clearInterval(_iIntervalID); } _times <= 0 || _times--; //如果是正数就 -- _self = $(_selector); //再次选择 if( _self.length ) { //判断是否取到 func && func.call(_self); clearInterval(_iIntervalID); } }, _interval); } return this; } $("table.syntaxhighlighter").wait(function() { $('table.syntaxhighlighter').append("<p class='cnblogs_code_footer'><span class='cnblogs_code_footer_icon'></span></p>"); }); $(document).on("click", ".cnblogs_code_footer",function(){ $(this).parents('table.syntaxhighlighter').css('display','inline-table');$(this).hide(); }); $('.nphpQianCont').viewer({navbar:true,title:false,toolbar:false,movable:false,viewed:function(){$('img').click(function(){$('.viewer-close').trigger('click');});}}); </script></body></html>