I'm using jQuery 2.1.3 on an Asp.net MVC site that renders partial views to certain site areas. A partial view can contain a script block that manipulates the area DOM. Partial views can also contain other partial views, and I can thus end up with several script tags.
This is usually not a problem. For simplicity I have made this example that alerts both 1 and 2:
$("body").html('<div id="target"><script>alert("dynamic dom 1");<\/script></div><div id="source"><script>alert("dynamic dom 2");<\/script></div>');
But if the first script manipulates the DOM, and moves the div containing the second script tag, the entire script isn't executed, and I only get alert 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>');
I'm not getting any JS errors that could stop execution!
I'm using jQuery.append()
, that should and in fact does move the div element.
I have tried using ready()
handlers to ensure that the DOM is fully loaded, but with the same effect.
This only seems to be a problem with dynamically loaded HTML. It works if I include the code in a plain html file, but with a single page MVC site that's not a usable workaround.
Is this a bug in jQuery.html()
or jQuery.append()
, or am I using it wrong?
EDIT: I'm not having problems adding the script tag(s). I'm not quite sure how added script tags are executed, and how one added script can affect the execution of the other. This could be the source of the problem. If you know how jQuery handles this, then please elaborate.
EDIT 2: I have recently made a big jQuery update, and this code worked with older jQuery versions. In fact, this works with jQuery-1.8.3, but not with jQuery-1.9.0 (or later). In this update jQuery marks inserted scripts as executed to prevent them from being run several times.
See: http://bugs.jquery.com/ticket/11795
and: http://jquery.com/upgrade-guide/1.9/#loading-and-running-scripts-inside-html-content
I know that it is poor practice to mix JS and HTML, but with MVC partial views it helps maintainability and overview to keep the JS and HTML in the same view file.
Nevertheless, I think that jQuery somehow wrongfully marks the second script to have been executed, when in fact it has not. Can someone please explain how scripts are marked as executed?