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

目的:获取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
				}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值