当前位置: 首页 > 工具软件 > ParseHTML > 使用案例 >

jQuery源码分析之parseHTML方法

杜联
2023-12-01

请首先阅读buildFrament以及正则表达式相关源码

源码如下:

//将字符串转化为节点数组!通过log可以知道
var rsingleTag = (/^<(\w+)\s*\/?>(?:<\/\1>|)$/);
jQuery.parseHTML1 = function( data, context, keepScripts ) {
	if ( !data || typeof data !== "string" ) {
		return null;
	}
	//只有两个参数的时候,第二个就是是否保存script标签,这时候context就没有传进来!
	if ( typeof context === "boolean" ) {
		keepScripts = context;
		context = false;
	}
	//如果只有两个参数那么context就是document对象!
	context = context || document;

	//如果不是单个标签那么parsed就是null,所谓的单个标签就是<div/>或者<div></div>但是<div>hello</div>不满足!
	var parsed = rsingleTag.exec( data ),
		//如果keepScripts是false,那么scripts就是
		scripts = !keepScripts && [];
	// Single tag
	if ( parsed ) {
		//如果是单个标签就调用相应的createElement方法,默认上下文是document!
		return [ context.createElement( parsed[1] ) ];
	}
    //如果不是单个标签就调用buildFragment方法,把html字符串传入,同时上下文也传入,第三个参数就是scripts!
	//如果paseHTML的第三个参数是false,那么这里的scripts就是一个数组,传递到buildFragment中会把所有的script标签放在里面
	//所以就要收到移除!
	parsed = jQuery.buildFragment( [ data ], context, scripts );
	if ( scripts && scripts.length ) {
		jQuery( scripts ).remove();
	}
	//buildFragment返回的是文档碎片,所以要变成数组,调用merge方法!
	return jQuery.merge( [], parsed.childNodes );
};

var result1=jQuery.parseHTML1("<div>我是内容1</div><script>alert('我是解析出来的js');<\/script><div>我是内容2</div>",document,true);
console.log(result1);
//通过firebug可以看到script标签已经添加到页面中了!但是必须添加到页面中才会执行!
$.each(result1,function(i,elem)
{
	$(elem).appendTo($("body"));
	
})

如果我们在调用parseHTML时候传入的第三个参数是false,那么就和下面的逻辑是一样的

 //如果我们parseHTML时候传入了false表示不保存script标签,那么所有的script标签全部在scripts这个数组中!
       var scripts = true && [];  
	   //创建了一个文档碎片!
var parsed = jQuery.buildFragment( [ "<div>我是内容1</div><script>alert('我是解析出来的js');<\/script><div>我是内容2</div>" ], document, scripts );  
		console.log(parsed);
		//从保存script的集合scripts中移除所有的scripts
		if ( scripts && scripts.length ) {  
		//scripts中放的全部是DOM,所以jQuery(scripts)是把其转化为jQuery对象!
              jQuery( scripts ).remove();  
             }  
	  console.log(parsed);
这时候如果没有remove方法的调用,第一个log打印的文档碎片是有script元素的,但是因为后面调用remove方法,所以这个集合中的script元素全部移除了!如果我们传入true表示会保存script元素,所以这时候我们不需要给buildFrament传入这个数组,因为没有意义,我们后面不需要单独操作这个集合移除所有的script!

init方法中有这样一段代码:

jQuery.merge( this, jQuery.parseHTML(match[1],context && context.nodeType ? context.ownerDocument || context : document,true) );
这样造成的结果就是我们我们创建script标签添加到页面中,如:

$("<script>alert('我被用于创建script标签')<\/script>").appendTo($("body"));
因为这个参数显然满足第一个字符是<,最后一个字符是>,而且长度大于3!

note:

(1)如果把上面的parseHTML1中最后一个参数修改为false那么传入buildFrament函数的就是一个数组,这个数组会放所有的script标签,所以返回的时候会判断这个数组的length,如果有script集合,那么必须手动移除!

(2)这个方法的作用是,如果是<div/>就创建相应的DOM元素,否则就创建一个文档碎片!但是函数的返回值始终是一个DOM数组!

 类似资料: