jquery源码分析——clean(elems,context,fragment,scripts)

来源:互联网 发布:卡尔维诺 知乎 编辑:程序博客网 时间:2024/05/29 18:05

目的:获取html代码段,生成DOM元素。

流程:1、修正context为正确的文本对象

            2、生成一个临时的div框,作为包裹必要的父对象。

            3、处理传入的元素数组,处理之。

            4、将处理好的元素数组安放在div里面。并且针对各个浏览器的特性进行适当的修正

            5、如果传入了一个fragment,则提取所有的script,插入到文本中。

clean : function(F, K, I) { //elems context fragment script //确保是document 等正确的文本对象,处理cotextK = K || document;if (typeof K.createElement === "undefined") {K = K.ownerDocument || K[0] && K[0].ownerDocument|| document}//只生成一个元素的话,直接createif (!I && F.length === 1 && typeof F[0] === "string") {var H = /^<(\w+)\s*\/?>$/.exec(F[0]);if (H) {return [ K.createElement(H[1]) ]}}//便利数据,尤父元素依次生成,div为一个临时框var G = [], E = [], L = K.createElement("div");o.each(F,function(P, S) {if (typeof S === "number") { //加一个“”自动变为字符串S += ""}if (!S) {return}if (typeof S === "string") { //stringObject.replace(regexp/substr,replacement), regexp 为要替换的子串 replacement规定了替换文本或生成替换文本的函数S = S   .replace(/(<(\w+)[^>]*?)\/>/g, //匹配类似于 <.../>这种 /g为全文搜索 修正自关闭标签 [^]表示非,所以是[^>]*表示任意多个不是>的字符function(U, V, T) {return T.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ? U //如果是自封闭的话 那返回自己,否则生成<></>.适用于处理$('<div  />')的情况: V+ "></"+ T+ ">"});var O = S.replace(/^\s+/, "") //去掉空白符,提取标签内容,并转为小写.substring(0, 10).toLowerCase();//有些标签必须要约束的,如<option>必须在<select></select>之内的var Q = !O.indexOf("<opt") //一种全新的startWith写法 !tags.indexOf('<opt>').indexOf返回o中<opt>的开始位置,如果是option,那么返回的是0,非一下就是1了. 然后返回Q是[1,"select multiple='multiple'>,</select>"],前面的数字指的是包在标签的第几层&& [1,"<select multiple='multiple'>","</select>" ]     || !O.indexOf("<leg")&& [ 1, "<fieldset>","</fieldset>" ]|| O.match(/^<(thead|tbody|tfoot|colg|cap)/)&& [ 1, "<table>","</table>" ]|| !O.indexOf("<tr")&& [ 2, "<table><tbody>","</tbody></table>" ]|| (!O.indexOf("<td") || !O.indexOf("<th"))&& [3,"<table><tbody><tr>","</tr></tbody></table>" ]|| !O.indexOf("<col")&& [2,"<table><tbody></tbody><colgroup>","</colgroup></table>" ]|| !o.support.htmlSerialize //标准浏览器会自动生成link标签&& [ 1, "div<div>","</div>" ]|| [ 0, "", "" ];L.innerHTML = Q[1] + S + Q[2]; //把标签包在父标签里面,放在div里面//得到最里面的标签while (Q[0]--) {L = L.lastChild}//不支持tbody的浏览器if (!o.support.tbody) {var R = /<tbody/i.test(S), N = !O   //正则 /i忽略大小写,是table,且没有tbody,N为table标签的childnodes,否则如果Q[1]是table,那么如果没有tbody,则N为L的childNodes,如果有N就是[].indexOf("<table")&& !R ? (L.firstChild&& L.firstChild.childNodes): Q[1] == "<table>"&& !R ? L.childNodes: [];for ( var M = N.length - 1; M >= 0; --M) {if (o.nodeName(N[M],"tbody")&& !N[M].childNodes.length) {N[M].parentNode.removeChild(N[M]) //之后没有子元素了,就直接移除}}}if (!o.support.leadingWhitespace   //浏览器不能读空白符,并且存在空白符&& /^\s/.test(S)) {L.insertBefore(K.createTextNode(S.match(/^\s*/)[0]), //在空白符前年面插入L.firstChildL.firstChild)}S = o.makeArray(L.childNodes)}if (S.nodeType) {G.push(S) //把所有的childNodes压栈} else {G = o.merge(G, S)}});//如果传入了文档片段fragment,则提取所有合法的script元素存入数组scripts,并把其他元素插入文档片段fragmentif (I) {for ( var J = 0; G[J]; J++) {if (o.nodeName(G[J], "script")  //提取所有的script标签,html的内容为<script 并且type为text/javascript&& (!G[J].type || G[J].type.toLowerCase() === "text/javascript")) {E.push(G[J].parentNode ? G[J].parentNode.removeChild(G[J]) : G[J]) //如果有父元素,则去掉script,否则把本身压栈} else {if (G[J].nodeType === 1) { //元素节点G.splice.apply(G,[ J + 1, 0 ].concat(o.makeArray(G[J].getElementsByTagName("script")))) //获取script标签里面的内容,放大片G里面}I.appendChild(G[J])}}return E}//最后返回转换后的DOM元素数组return G}


0 0
原创粉丝点击