目的:获取html代码段,生成DOM元素。
流程:1、修正context为正确的文本对象
2、生成一个临时的div框,作为包裹必要的父对象。
3、处理传入的元素数组,处理之。
4、将处理好的元素数组安放在div里面。并且针对各个浏览器的特性进行适当的修正
5、如果传入了一个fragment,则提取所有的script,插入到文本中。
clean : function(F, K, I) { //elems context fragment script
//确保是document 等正确的文本对象,处理cotext
K = K || document;
if (typeof K.createElement === "undefined") {
K = K.ownerDocument || K[0] && K[0].ownerDocument
|| document
}
//只生成一个元素的话,直接create
if (!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.firstChild
L.firstChild)
}
S = o.makeArray(L.childNodes)
}
if (S.nodeType) {
G.push(S) //把所有的childNodes压栈
} else {
G = o.merge(G, S)
}
});
//如果传入了文档片段fragment,则提取所有合法的script元素存入数组scripts,并把其他元素插入文档片段fragment
if (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
}