【问题标题】:jQuery - script tags in the HTML are parsed out by jQuery and not executedjQuery - HTML 中的脚本标签被 jQuery 解析出来而不被执行
【发布时间】:2010-04-23 14:26:12
【问题描述】:

我有一个这样的 HTML 页面:

<html>
<body>
<div id='something'>
    ...
    <script>
    var x = 'hello world';
    </script>
    ...
</div>
</body>
</html>

在另一个页面上,我正在这样做:

$.ajax({
    url: 'example.html',
    type: 'GET',
    success: function(data) {
        $('#mydiv').html($(data).find('#something').html());
        alert(x);
    }
});

然而,jQuery 并没有执行第一个文件中的 javascript,即使文档说它执行了。我怎样才能做到这一点?

编辑:不幸的是,在我正在开发的实际应用程序中,我无法控制“包含”页面的内容。我们在同一个域中,但我无法修改它输出的代码,因为它是我们的 IT 部门不允许我们修改的打包产品。

【问题讨论】:

  • 您是否检查过如果您在脚本本身(即“包含”页面内)执行alert() 会发生什么?
  • 好吧,如果你不能改变它,你可以通过添加一些调试代码来检查我的理论,看看$(data).html() 的样子。如果它不包含脚本标签,那就是问题所在。您可能想查看 jQuery 源代码,看看它是如何去除脚本的;它使用了一个相当丑陋的正则表达式,但也许你可以自己剥离脚本然后执行它们。

标签: javascript jquery


【解决方案1】:

正如尖尖的指出请原谅双关语),当您将 HTML 传递给$() 时,jQuery 会混淆 SCRIPT 标签。但它不会删除它们——它只是将它们添加到从您的 HTML 生成的 DOM 集合中。您可以像这样执行脚本:

$.ajax({
    url: 'example.html',
    type: 'GET',
    success: function(data) {

        var dom = $(data); 
        $('#mydiv').html(dom.find('#something').html());
        dom.filter('script').each(function(){
            $.globalEval(this.text || this.textContent || this.innerHTML || '');
        });
    }
});

【讨论】:

  • 如果 jQuery 公开它的 evalScript 实现就好了。然后你可以完成dom.filter('script').each($.evalScript),它也可以处理带有src 属性的脚本,就像其他dom 操作方法一样。
  • 对我来说,如果我在替换内容后执行dom.filter,它就可以工作。对我来说似乎合乎逻辑,但与似乎是合格的答案不同(见上文)。有人可以纠正这个吗?
  • 我认为 Pheonix_uy 所做的编辑是准确的。 dom 是从 ajax 调用返回的数据。用 $('#mydiv').filter 替换 dom.filter 还是我错过了什么?
【解决方案2】:

作为@James 回答的替代方案,可以使用$.parseHTML() 解析HTML 字符串,注意将包含脚本的布尔标志添加到true

$.ajax({
    url: 'example.html',
    type: 'GET',
    success: function(data) {

        var content = $($.parseHTML(data, document, true)).find('#something');
        $('#mydiv').html(content);

    }
});

通过这种方式可以执行任何嵌入在下载文本中的脚本。

【讨论】:

  • 感谢 guari 的建议 - 这应该被投票,因为它是一个更有效的选择。
【解决方案3】:

我对此并不完全确定,但有可能发生的事情是当 jQuery 从$(data) 构建片段时,脚本标签此时会丢失。

如果你能把包含的页面安排成真的只是一个片段:

<div id='something'>
  <!-- ... -->
  <script>var x = 'hello world';</script>
</div>

没有任何其他周围的东西,那么你的成功回调可以这样做:

success: function(data) {
  $('#mydiv').html(data);
}

现在这些脚本标签将被 jQuery html() 函数注意到,该函数会显式查找它们并将它们删除。然而,它确实保留了这些脚本块,并在完成更新目标内容后执行它们。

【讨论】:

    【解决方案4】:

    方案一:服务器返回准确的内容

    $.ajax({
        url: 'example.html',
        type: 'GET',
        success: function(data) {
    
            $('#mydiv').html(data);
    
        }
    });
    

    解决方案2:使用innerHTML

    $.ajax({
        url: 'example.html',
        type: 'GET',
        success: function(data) {
    
            var dom = $(data);
            $('#mydiv').html(dom.find('#something')[0].innerHTML);
    
        }
    });
    

    【讨论】:

      【解决方案5】:

      我希望第一页正在执行 JavaScript,但是无法从第二页访问,因此 alert(x) 将不起作用

      如果您想返回 x,您必须将其输出到 AJAX 响应。

      【讨论】:

      • 啊 - 我正要说为什么这不是问题,但我想我只是想通了。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-06
      • 2011-10-02
      • 1970-01-01
      相关资源
      最近更新 更多