jQuery - HTML 中的脚本标签被 jQuery 解析而不执行

IT技术 javascript jquery
2021-02-10 20:13:33

我有一个像这样的 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 部门不允许我们修改的打包产品。

5个回答

正如 Pointy指出的(请原谅双关语),当您将 HTML 传递给$(). 但是它并没有删除它们——它只是将它们添加到从您的 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 操作方法一样。
2021-03-14 20:13:33
对我来说,它只是有效,如果我dom.filter在替换内容之后对我来说似乎合乎逻辑,但与似乎是合格的答案不同(见上文)。有人可以纠正这个吗?
2021-04-04 20:13:33
我认为 Pheonix_uy 所做的编辑是准确的。dom 是从 ajax 调用返回的数据。用 $('#mydiv').filter 替换 dom.filter 还是我遗漏了什么?
2021-04-08 20:13:33

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

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

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

    }
});

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

感谢 guari 的建议 - 这应该被投票赞成,因为它是一个更有效的选择。
2021-04-12 20:13:33

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

如果您可以将包含的页面安排为真的只是一个片段:

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

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

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

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

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

$.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);

    }
});

我希望第一页正在执行 JavaScript,但是这不能从第二页访问,所以alert(x)不会工作

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

啊 - 我正要说为什么这不是问题,但我想我刚刚弄清楚交易是什么。
2021-04-09 20:13:33