我通过加载页面$.ajax()并插入部分结果到页面的相应部分:
$.ajax({
url: '/whole_page.html',
success: function (data, status, xhr) {
$result = $(xhr.responseText);
$('#menu').html($('#menu', $result).html());
$('#content').html($('#content', $result).html());
}
});
Run Code Online (Sandbox Code Playgroud)
像魅力一样,但我遇到了问题.
现在我的页面包含一些特定于页面的JS,在获取和插入结果时必须执行这些JS.据我所知,script如果你从HTML文本构造一个jQuery对象并对它进行查询,jQuery将不会返回元素(我已经做了一个小提示来演示).所以,我无法通过jQuery有选择地只插入我想要的脚本.
所以我似乎必须script自己从响应文本中提取元素.基本上,我正在寻找正确的方法来做到这一点.这是我到目前为止所提出的:
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);
}
Run Code Online (Sandbox Code Playgroud)
虽然我还没有在任何糟糕的浏览器上测试过它,但效果还不错.无论如何,复制jQuery的这些基本功能只是为了避免其中一个功能(特殊script处理)感到不舒服.正如在小提琴中可以看到的那样,jQuery对象实际上确实包含scripts,但它不会返回类似.html()或者类似的东西.get().我错过了一些明显的做法吗?
注意:一旦jQuery的内部parseHTML函数暴露出来,这整个主题都没有实际意义
注2:我还阅读了尝试从jQuery ajax get响应中选择脚本标签,但是接受的答案是"你不能",然后是"使用正则表达式".两者都不令人满意
在 jQuery 1.8.0b1 中,您现在可以使用该$.parseHTML()方法来简化此操作。
$.parseHTML(xhr.responseText,true)将为您提供一个包含脚本元素的 jQuery 对象。然后,您可以提取脚本标签并在附加 html 后附加或执行它们。
$.ajax({
url: '/whole_page.html',
success: function (data, status, xhr) {
var $result = $.parseHTML(xhr.responseText,true),
$scripts = $result.find("script").add($result.filter("script")).detach();
$('#menu').html($('#menu', $result).html());
$('#content').html($('#content', $result).html());
$('head').append($scripts);
}
});
Run Code Online (Sandbox Code Playgroud)
您可能必须根据具体情况过滤脚本,以避免重复包含 jQuery。这将取决于您正在加载的内容。
如果升级 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 ], context, scripts ? null : [] );
return jQuery.merge( [],
(parsed.cacheable ? jQuery.clone( parsed.fragment ) : parsed.fragment).childNodes );
}
}
})(jQuery);
Run Code Online (Sandbox Code Playgroud)