我在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错误地标记了第二个脚本已被执行,而事实上它并没有。有人可以解释如何将脚本标记为已执行吗?
答案 0 :(得分:0)
似乎从jQuery 1.9.0开始,当动态插入包含脚本标记的DOM元素时,jQuery首先扫描/解析输入DOM并将脚本标记为已执行。然后它遍历DOM并评估脚本。
请参阅:http://jquery.com/upgrade-guide/1.9/#loading-and-running-scripts-inside-html-content
当脚本标记随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")');
使用&#34; _myWidget.cshtml&#34;:
<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>
和&#34; _myWidgetContent.cshtml&#34;:
<div id="source"></div>
<script>
alert("dynamic dom 2");
//Something specific to this partial view
$("#source").click(function() { alert("clicked") });
</script>