我遇到一种情况,我在AJAX调用后从服务器返回HTML响应。我需要将特定元素及其子元素拉出,并将其注入DOM中。
目前我的AJAX回调类似于:
var onSuccess = function (rawData) {
var rawData = $(rawData);
var data = rawData.find("#foo");
$("#bar").append(data);
};
除非#foo
包含<script>
元素,否则此工作正常。经过多次探讨,我已经确定问题出现在第一步:
var rawData = $(rawData);
将HTML传递给jQuery会将所有<script>
元素从其原始上下文中拉出来并使其成为顶级元素。随后的.find("#foo")
无法将之前嵌套的<script>
元素带到该位置,因为它们已经被移动到其他位置。
当我将原始HTML直接注入DOM时,一切正常,但是我们的系统已经过时了,需要大量的按摩才能将其返回的内容限制为感兴趣的元素,所以现在我需要能够扫描总响应,只采取我需要的。其中包括<script>
个元素。
有什么建议吗?
[跟踪处理] 谢谢大家的帮助。
我最终根据我的需要调整this solution,使我的AJAX成功回调看起来像这样:
var onSuccess = function (rawData) {
var data = $(rawData);
var scripts = data.filter("script[someAttribute='someValue']");
var elementOfInterest = data.find("#foo"); // scripts above used to live in #foo
$("#target").append(elementOfInterest);
$("body").append(scripts);
};
注意,这需要我为我想要传承的嵌套脚本元素添加一个特殊属性。
答案 0 :(得分:1)
此函数接受一个html字符串,从中删除脚本,将html附加到目标,然后执行脚本。这个函数结合ajax来获取html应该可以解决你的问题。
function cleanInsert(html, target, filter) {
var outHTML = html, $content = $(target);
outHTML = outHTML.replace(/<script/ig, "<div class='iscript'").replace(/<\/script/ig, '</script');
outHTML = $(outHTML);
if (filter) {
outHTML = filter.call(outHTML);
}
var scripts = outHTML.filter('div.iscript').detach();
$content.html(outHTML);
scripts.each(function() {
var $this = $(this),
s = document.createElement("script");
if ($this.attr('src') != "") {
s.src = $this.attr('src');
} else {
s.nodeValue = $this.text();
}
$content[0].appendChild(s);
});
}
用法:
$.get("myurl.php",function(html){
cleanInsert(html,"#bar", function(){
return this.find("#foo");
});
});
该功能改编自history.js示例中的代码。
但请注意,HTML中包含的脚本必须是顶级的,例如<head></head>
或<body>
的直接子级,或者作为顶级元素。如果这是一个问题,则需要调整该功能以进行补偿。
更新:啊,这不考虑你只需要更新。#foo
内的html。
更新:请务必注意,使用document.write()
的任何脚本都无法正常使用此功能或因document.write()
工作原因而附加html的任何其他方法。