0

我有一种情况,在 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>元素。

有什么建议么?

[后续] 谢谢大家的帮助。

我最终根据我的需要调整了这个解决方案,使我的 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);
};

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

4

1 回答 1

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>,或者作为顶级元素。如果这是一个问题,则需要调整该功能以进行补偿。

更新:啊,这没有考虑到你只想要 html 中的#foo. 更新。

更新:重要的是要注意,由于工作document.write()方式的原因,任何使用此功能或任何其他附加 html 的方法都无法正常运行的脚本document.write()

于 2012-06-07T21:04:28.443 回答