jQuery在HTML字符串中评估JavaScript并发症

时间:2011-04-18 16:27:10

标签: javascript jquery jquery-selectors

这让我发疯了......

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

最初,我有以下JavaScript代码,只要新的HTML的AJAX请求完成就会运行:

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

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

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

我已经读过jQuery将使用html()函数的HTML字符串参数评估任何脚本 - 但是,似乎问题是在调用之前脚本被剥离了。 看过萤火虫之后,似乎正在发生以下情况:

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

有没有人有任何建议? 提前谢谢。

5 个答案:

答案 0 :(得分:4)

给出了quick test (fiddle),给出了以下标记为字符串:

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

jQuery将生成一个像

这样的对象
> [0]: #root
> [1]: script

[0]将包含#root中除脚本之外的所有html,脚本被分成各自的对象。这似乎适用于标记中的所有脚本。

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

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

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

答案 1 :(得分:1)

编辑没关系;我想你在这里沉没了。一旦将内容移交给jQuery,我就很确定你的脚本被删除了。如果“newContent”实际上是“本机”页面的一部分,那么下面的东西可以工作,但因为它是在jQuery实例化的那个片段中,所以为时已晚。

<击> 我认为这会有效,但我承认我没有尝试使用像你所拥有的加载文件:

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

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

答案 2 :(得分:1)

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

从讨论开始:

  

如果要选择/遍历HTML字符串的一部分,并且希望HTML字符串中的<script>被执行,则需要在选择/遍历之前将HTML字符串插入DOM中。

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

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

  2. $(newHtmlContent)中拉出脚本网址,使用$.getScript()检索并执行每个网址,然后将检索到的元素添加到DOM中。这更令人痛苦,但它应该可以正常工作,而且您不必在DOM中插入不必要的内容。

答案 3 :(得分:0)

您可以尝试的一件事就是提取包含的<script>元素和eval()元素,或者将它们附加到页面的head

答案 4 :(得分:0)

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

//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());