jQuery 评估 HTML 字符串中的 JavaScript,但很复杂

发布于 2024-11-01 23:00:03 字数 812 浏览 1 评论 0原文

这让我发疯...

我想做的是更新网页的一部分,并且出于不值得解释的原因,该请求要求一个全新的 HTML 页面(包括其头部),然后仅提取包含在指定元素(由 ID 标识)内的 HTML。

最初,我有以下 JavaScript 代码,每当对新 HTML 的 AJAX 请求完成时,该代码都会运行:

var $newContent = $(newHtmlContent);
loadingElement.innerHTML = $("#" + loadingElementId, $newContent).html();

这很棒,直到我加载了一些 HTML,该 HTML 包含在指定元素中,其中包含一些需要运行的脚本,所以我将其更改为:

var $newContent = $(newHtmlContent);
$(loadingElement).html($("#" + loadingElementId, $newContent).html());

我已读到 jQuery 将使用 html() 函数的 HTML 字符串参数评估任何脚本 - 然而,问题似乎是脚本在此调用之前被剥离。 浏览完 Firebug 后,似乎发生了以下情况:

$(newHtmlContent) // includes all 'script' elements
$("#" + loadingElementId, $newContent) // has no scripts
$("script", $newContent) // empty jQuery object

有人有任何建议吗? 提前致谢。

This is driving me crazy...

What I am trying to do is update a portion of a webpage, and for reasons not worth explaining, the request is asking for a whole new HTML page (including its head) and then pulling out only the HTML that was contained within a specified element (identified by an ID).

Originally, I had the following JavaScript code that would run whenever an AJAX request for new HTML completed:

var $newContent = $(newHtmlContent);
loadingElement.innerHTML = $("#" + loadingElementId, $newContent).html();

This was great until I had a bit of HTML that was loaded that, contained within the specified element, included some scripts that needed to be run, so I changed it to this:

var $newContent = $(newHtmlContent);
$(loadingElement).html($("#" + loadingElementId, $newContent).html());

I have read that jQuery will evaluate any scripts with the HTML string argument of the html() function - however, it seems the issue is that the scripts are stripped before this call.
Having had a look through firebug the following seems to be happening:

$(newHtmlContent) // includes all 'script' elements
$("#" + loadingElementId, $newContent) // has no scripts
$("script", $newContent) // empty jQuery object

Does anyone have any suggestions?
Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

﹏雨一样淡蓝的深情 2024-11-08 23:00:03

进行了 快速测试 (fiddle),给出以下字符串标记:

<div id="root">
    <div>some dynamic content</div>
    <script type="text/javascript">alert("hello");</script>
    <div class="desiredElement">after script</div>
</div>

对象

> [0]: #root
> [1]: script

jQuery 将生成一个类似< 的 code>[0] 将包含 #root 中除脚本之外的所有 html,脚本被分成自己的对象。对于标记内的所有脚本来说似乎都是如此。

所以你可以这样做来运行脚本:

var $new = $(dynamicContent); // dynamicContent is string
var $desired = $new.find('.desiredElement');

$new.eq(1).appendTo('body'); // run the script

Did a quick test (fiddle), given the following markup as string:

<div id="root">
    <div>some dynamic content</div>
    <script type="text/javascript">alert("hello");</script>
    <div class="desiredElement">after script</div>
</div>

jQuery will produce an object like

> [0]: #root
> [1]: script

[0] will contain all of the html in #root except for the script, the scripts are separated into their own objects. This seems to be true for all scripts within the markup.

So you could do something like this to run the script:

var $new = $(dynamicContent); // dynamicContent is string
var $desired = $new.find('.desiredElement');

$new.eq(1).appendTo('body'); // run the script
葮薆情 2024-11-08 23:00:03

编辑没关系;我想你已经沉没在这里了。一旦您将内容移交给 jQuery,我就很确定您的脚本已被删除。如果“newContent”实际上是“本机”页面的一部分,下面的技巧就会起作用,但因为它位于由 jQuery 实例化的片段中,所以为时已晚。

<罢工>
认为这会起作用,但我承认我还没有尝试过像你所拥有的那样加载文档:

$('#loadingElement').html($('#' + loadingElementId, $newContent)[0].innerHTML);

这个想法是在拉出时绕过 jQuery加载部分的内容。

edit Never mind; I think you're sunk here. As soon as you hand over the content to jQuery, I'm pretty sure that your scripts are stripped out. The stuff trick below would work if "newContent" were actually part of the "native" page, but because it's in that fragment instantiated by jQuery, it's too late.


I think this will work, but I admit I haven't tried it with a loaded document like what you've got:

$('#loadingElement').html($('#' + loadingElementId, $newContent)[0].innerHTML);

The idea is to bypass jQuery when pulling out the contents of the loaded portion.

倾`听者〃 2024-11-08 23:00:03

这里有一个关于这个问题的长解释: http://forum.jquery.com/topic/jquery-removing-script-tags-from-html-string-when-using-html

从该讨论中:

如果你想选择/遍历HTML字符串的一部分,并且希望执行HTML字符串中的

所以看起来问题在于您试图从返回的 HTML 中提取元素,而不先将其插入到 DOM 中。两种可能的解决方案:

  1. 将整个返回的 HTML 插入到 DOM 中。脚本标签将执行。然后删除不需要的部分。这并不理想,因为它可能会显示您不想要的内容,除非您先隐藏 loadingElement 并在完成后显示。

  2. $(newHtmlContent)中提取脚本URL,使用$.getScript()检索并执行每个URL,然后添加将检索到的元素放入 DOM 中。这比较麻烦,但应该可以正常工作,而且您不必将不必要的内容插入到 DOM 中。

There's a long explanation of this issue here: http://forum.jquery.com/topic/jquery-removing-script-tags-from-html-string-when-using-html

From that discussion:

If you want to select/traverse part of an HTML string, and you want the <script> within the HTML string to be executed, you need to insert the HTML string into the DOM before selecting/traversing.

So it looks like the problem is that you're trying to pull elements out of the returned HTML without inserting it into the DOM first. Two possible solutions:

  1. Insert the entire returned HTML into the DOM. The script tags will execute. Then remove the parts you don't need. It's not ideal, as it might display content you don't want, unless you hide the loadingElement first and show when you're done.

  2. Pull out the script URLs from $(newHtmlContent), use $.getScript() to retrieve and execute each URL, then add the retrieved elements into the DOM. It's more of a pain, but it should work fine, and you don't have to insert unnecessary content into the DOM.

可是我不能没有你 2024-11-08 23:00:03

您可以尝试的一件事是取出包含的

One thing you could try would be to pull out the contained <script> elements and either eval() them or append them into the head of the page.

你没皮卡萌 2024-11-08 23:00:03

我也在这里猜测,但是怎么样:

//scripts will be executed and HTML put into loadingElement
$('#loadingElement').html(newHtmlContent); 

//find the specified element under #loadingElement, get it's HTML 
//and set it as the HTML for #loadingElement
$('#loadingElement').html($('#loadingElement').find('#idToFind').html());

I'm guessing here as well but how about:

//scripts will be executed and HTML put into loadingElement
$('#loadingElement').html(newHtmlContent); 

//find the specified element under #loadingElement, get it's HTML 
//and set it as the HTML for #loadingElement
$('#loadingElement').html($('#loadingElement').find('#idToFind').html());
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文