Javascript 动态添加的脚本标记不';使用jQuery移动时不会执行
我在一个Asp.NETMVC站点上使用jQuery 2.1.3,该站点呈现某些站点区域的部分视图。 局部视图可以包含操纵区域DOM的脚本块。局部视图还可以包含其他局部视图,因此我可以得到几个脚本标记 这通常不是问题。为了简单起见,我制作了这个示例,它同时提醒1和2:Javascript 动态添加的脚本标记不';使用jQuery移动时不会执行,javascript,jquery,asp.net-mvc,Javascript,Jquery,Asp.net Mvc,我在一个Asp.NETMVC站点上使用jQuery 2.1.3,该站点呈现某些站点区域的部分视图。 局部视图可以包含操纵区域DOM的脚本块。局部视图还可以包含其他局部视图,因此我可以得到几个脚本标记 这通常不是问题。为了简单起见,我制作了这个示例,它同时提醒1和2: $("body").html('<div id="target"><script>alert("dynamic dom 1");<\/script></div><div id="
$("body").html('<div id="target"><script>alert("dynamic dom 1");<\/script></div><div id="source"><script>alert("dynamic dom 2");<\/script></div>');
$(“body”).html('alert(“动态dom 1”);alert(“动态dom 2”);');
但如果第一个脚本操纵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>');
$(“body”).html('alert(“dynamicdom1”);$(“#target”).append($(“#source”);alert(“dynamicdom2”);
我没有收到任何可能停止执行的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将插入的脚本标记为已执行,以防止它们被多次运行
见:
以及:
我知道混合使用JS和HTML是一种糟糕的做法,但是使用MVC部分视图,将JS和HTML保持在同一个视图文件中有助于维护性和概述
尽管如此,我认为jQuery在某种程度上错误地将第二个脚本标记为已执行,而实际上它并未执行。有人能解释一下脚本是如何被标记为已执行的吗?一般来说
从jQuery 1.9.0来看,当动态插入包含脚本标记的DOM元素时,jQuery首先扫描/解析输入DOM,并在执行时标记脚本。然后它遍历DOM并计算脚本
见:
当使用jquery.append()
移动脚本标记时,它已经被标记为已执行,因此不会进行计算
脚本标记在DOM层次结构中的何处移动并不重要。第一个$.html()
将其标记为已执行,当移动它时,后续的$.append()
不知道它实际上尚未执行
要明确评估它,可以执行eval($(“#源脚本”).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>');
使用“\u myWidget.cshtml”:
@Html.Partial(“\u myWidgetContent”)
警报(“动态dom 1”);
$(“#目标”)。追加($(“#源”)//或者其他一些操作小部件DOM的设置
eval($(“#源脚本”).text();
和“_myWidgetContent.cshtml”:
警报(“动态dom 2”);
//某些特定于这个局部视图的东西
$(“#源”)。单击(函数(){alert(“clicked”)};
脚本是否需要在DOM中存在可能的重复,难道不能直接执行吗?
$("body #someContainer").html('@Html.Partial("_myWidget")');
<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>
<div id="source"></div>
<script>
alert("dynamic dom 2");
//Something specific to this partial view
$("#source").click(function() { alert("clicked") });
</script>