簡體   English   中英

使用jQuery移動時,動態添加的腳本標簽不執行

[英]Dynamically added script tag doesn't execute when moved with jQuery

我在Asp.net MVC網站上使用jQuery 2.1.3,該網站呈現了某些站點區域的局部視圖。 局部視圖可以包含一個操作區域DOM的腳本塊。 局部視圖還可以包含其他局部視圖,因此,我可以得到幾個腳本標簽。

通常這不是問題。 為簡單起見,我制作了此示例,該示例同時警告1和2:

$("body").html('<div id="target"><script>alert("dynamic dom 1");<\/script></div><div id="source"><script>alert("dynamic dom 2");<\/script></div>'); 

但是,如果第一個腳本操縱DOM,並移動包含第二個腳本標簽的div, 則不會執行整個腳本 ,而我只會收到警報1:

$("body").html('<div id="target"><script>alert("dynamic dom 1");$("#target").append($("#source"));<\/script></div><div id="source"><script>alert("dynamic dom 2");<\/script></div>'); 

我沒有收到任何可能停止執行的JS錯誤!

我正在使用jQuery.append() ,它確實應該移動 div元素。

我嘗試使用ready()處理程序來確保DOM已完全加載,但效果相同。

對於動態加載的HTML,這似乎只是一個問題。 如果我將代碼包含在純HTML文件中,但是使用單個頁面的MVC網站,則不是可行的解決方法,它可以工作。

這是jQuery.html()還是jQuery.append()錯誤,還是我使用錯了?

編輯:我沒有添加腳本標記的問題。 我不太確定如何執行添加的腳本標記,以及一個添加的腳本如何影響另一個腳本的執行。 這可能是問題的根源。 如果您知道jQuery如何處理此問題,請詳細說明。

編輯2:我最近做了一個很大的jQuery更新,並且此代碼可用於舊的jQuery版本。 實際上,這適用於jQuery-1.8.3,但不適用於jQuery-1.9.0(或更高版本)。 在此更新中,jQuery將插入的腳本標記為已執行,以防止它們多次運行。

請參閱: http//bugs.jquery.com/ticket/11795

和: http : //jquery.com/upgrade-guide/1.9/#loading-and-running-scripts-inside-html-content

我知道將JS和HTML混合使用是不好的做法,但是使用MVC部分視圖,有助於將JS和HTML保留在同一視圖文件中的可維護性和概述。

盡管如此,我認為jQuery某種程度上錯誤地將第二個腳本標記為已經執行,而實際上卻沒有。 有人可以解釋腳本如何標記為已執行嗎?

一般來說

從jQuery 1.9.0看來,當動態插入包含腳本標簽的DOM元素時,jQuery首先掃描/解析輸入的DOM,並在執行時對腳本進行標簽。 然后,它遍歷DOM並評估腳本。

參見: http : //jquery.com/upgrade-guide/1.9/#loading-and-running-scripts-inside-html-content

當使用jquery.append()移動腳本標簽時, jquery.append()其標記為已執行,因此將不進行評估。

在DOM層次結構中腳本標記移入/移出的位置並不重要。 第一個$.html()將其標記為已執行,而在移動它時,隨后的$.append()不知道它實際上尚未執行。

要明確評估它,可以執行eval($("#source script").text()) ,即:

$("body").html('<div id="target"><script>alert("dynamic dom 1");$("#target").append($("#source"));eval($("#source script").text());</script></div><div id="source"><script>alert("dynamic dom 2");</script></div>');

對於Asp.net MVC

這將有助於Asp.net MVC部分視圖,在這些視圖中,您希望使JS靠近其操縱的DOM元素(即,在同一文件中),例如:

$("body #someContainer").html('@Html.Partial("_myWidget")');

與“ _myWidget.cshtml”:

<div id="target">@Html.Partial("_myWidgetContent")</div>
<script>
    alert("dynamic dom 1");
    $("#target").append($("#source")); //or some other setup that manipulates the widget DOM
    eval($("#source script").text();
</script>

和“ _myWidgetContent.cshtml”:

<div id="source"></div>
<script>
    alert("dynamic dom 2");
    //Something specific to this partial view
    $("#source").click(function() { alert("clicked") });
</script>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM