[英]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部分視圖,在這些視圖中,您希望使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.