我正在通过$.ajax()加载页面并将部分结果插入页面的相应部分:
$.ajax({
url: '/whole_page.html',success: function (data,status,xhr) {
$result = $(xhr.responseText);
$('#menu').html($('#menu',$result).html());
$('#content').html($('#content',$result).html());
}
});
像魅力一样,但我遇到了问题.
现在我的页面包含一些特定于页面的JS,在获取和插入结果时必须执行这些JS.据我所知,如果你从HTML文本构造一个jQuery对象并对它进行查询,jQuery将不会返回脚本元素(我要made a fiddle来演示).所以,我无法通过jQuery有选择地只插入我想要的脚本.
所以我似乎必须自己从响应文本中提取脚本元素.基本上,我正在寻找正确的方法来做到这一点.这是我到目前为止所提出的:
function pullScripts(text) {
var frag = document.createDocumentFragment(),div = document.createElement('div'),scriptElements
;
// This is roughly how jQuery finds the scripts when cleaning text
frag.appendChild(div);
div.innerHTML = text;
scriptElements = div.getElementsByClassName('class-for-scripts-that-we-want');
$('head').append(scriptElements);
}
虽然我还没有在任何糟糕的浏览器上测试过它,但效果还不错.无论如何,复制jQuery的这些基本功能只是为了避免其中一个功能(特殊脚本处理)感到不舒服.从小提琴中可以看出,jQuery对象实际上确实包含脚本,但它不会返回类似.html()或.get()的东西.我错过了一些明显的做法吗?
注意:一旦jQuery的内部parseHTML函数被公开,这整个主题都没有实际意义
注2:我也阅读了Trying to select script tags from a jQuery ajax get response但是接受的答案是“你不能”,其次是“使用正则表达式”.两者都不令人满意
最佳答案
在jQuery 1.8.0b1中,您现在可以使用
$.parseHTML()
方法来简化这一过程.
$.parseHTML(xhr.responseText,true)将为您提供包含脚本元素的jQuery对象.然后,您可以在附加html后提取脚本标记并附加或执行它们.
$.ajax({
url: '/whole_page.html',xhr) {
var $result = $.parseHTML(xhr.responseText,true),$scripts = $result.find("script").add($result.filter("script")).detach();
$('#menu').html($('#menu',$result).html());
$('head').append($scripts);
}
});
您可能必须过滤脚本,以避免双重包括jQuery的具体情况.这取决于您加载的内容.
如果升级jQuery不是一个选项,你可以采用$.parseHTML的实现并将其作为插件包含在当前的jQuery中
(function($) {
if (!$.parseHTML) {
var rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/;
// data: string of html
// context (optional): If specified,the fragment will be created in this context,defaults to document
// scripts (optional): If true,will include scripts passed in the html string
$.parseHTML = function( data,context,scripts ) {
var parsed;
if ( !data || typeof data !== "string" ) {
return null;
}
if ( typeof context === "boolean" ) {
scripts = context;
context = 0;
}
context = context || document;
// Single tag
if ( (parsed = rsingleTag.exec( data )) ) {
return [ context.createElement( parsed[1] ) ];
}
parsed = jQuery.buildFragment( [ data ],scripts ? null : [] );
return jQuery.merge( [],(parsed.cacheable ? jQuery.clone( parsed.fragment ) : parsed.fragment).childNodes );
}
}
})(jQuery);