将传入的HTML传递到jQuery会将脚本元素移出其原始上下文

时间:2012-06-07 20:10:46

标签: jquery ajax

我遇到一种情况,我在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);
};

注意,这需要我为我想要传承的嵌套脚本元素添加一个特殊属性。

1 个答案:

答案 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的任何其他方法。