使用jQuery

时间:2015-06-03 13:23:14

标签: javascript jquery asp.net-mvc

我在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错误地标记了第二个脚本已被执行,而事实上它并没有。有人可以解释如何将脚本标记为已执行吗?

1 个答案:

答案 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

这将有助于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>