Added a fix for bug #1698, in which injected scripts were executed out of order, in relation to the DOM.

This commit is contained in:
John Resig 2007-10-17 22:42:12 +00:00
parent a2fc65fd32
commit e287007f6a
2 changed files with 36 additions and 20 deletions

View file

@ -461,39 +461,51 @@ jQuery.fn = jQuery.prototype = {
if ( table && jQuery.nodeName( this, "table" ) && jQuery.nodeName( elems[0], "tr" ) ) if ( table && jQuery.nodeName( this, "table" ) && jQuery.nodeName( elems[0], "tr" ) )
obj = this.getElementsByTagName("tbody")[0] || this.appendChild( document.createElement("tbody") ); obj = this.getElementsByTagName("tbody")[0] || this.appendChild( document.createElement("tbody") );
var scripts = jQuery( [] );
jQuery.each(elems, function(){ jQuery.each(elems, function(){
var elem = clone ? var elem = clone ?
this.cloneNode( true ) : this.cloneNode( true ) :
this; this;
if ( !evalScript( 0, elem ) ) if ( jQuery.nodeName( elem, "script" ) ) {
// If scripts are waiting to be executed, wait on this script as well
if ( scripts.length )
scripts = scripts.add( elem );
// If nothing is waiting to be executed, run immediately
else
evalScript( 0, elem );
} else {
// Remove any inner scripts for later evaluation
if ( elem.nodeType == 1 )
scripts = scripts.add( jQuery( "script", elem ).remove() );
// Inject the elements into the document
callback.call( obj, elem ); callback.call( obj, elem );
}
}); });
scripts.each( evalScript );
}); });
} }
}; };
function evalScript( i, elem ) { function evalScript( i, elem ) {
var script = jQuery.nodeName( elem, "script" ); if ( elem.src )
jQuery.ajax({
url: elem.src,
async: false,
dataType: "script"
});
if ( script ) { else
if ( elem.src ) jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
jQuery.ajax({
url: elem.src,
async: false,
dataType: "script"
});
else if ( elem.parentNode )
jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" ); elem.parentNode.removeChild( elem );
if ( elem.parentNode )
elem.parentNode.removeChild( elem );
} else if ( elem.nodeType == 1 )
jQuery( "script", elem ).each( evalScript );
return script;
} }
jQuery.extend = jQuery.fn.extend = function() { jQuery.extend = jQuery.fn.extend = function() {

View file

@ -834,8 +834,10 @@ test("val(String)", function() {
ok( $("#select1").val() == "3", "Check for modified (via val(String)) value of select element" ); ok( $("#select1").val() == "3", "Check for modified (via val(String)) value of select element" );
}); });
var scriptorder = 0;
test("html(String)", function() { test("html(String)", function() {
expect(3); expect(9);
var div = $("div"); var div = $("div");
div.html("<b>test</b>"); div.html("<b>test</b>");
var pass = true; var pass = true;
@ -850,6 +852,8 @@ test("html(String)", function() {
$("#main").html('foo <form><script type="text/javascript">ok( true, "$().html().evalScripts() Evals Scripts Twice in Firefox, see #975" );</script></form>'); $("#main").html('foo <form><script type="text/javascript">ok( true, "$().html().evalScripts() Evals Scripts Twice in Firefox, see #975" );</script></form>');
$("#main").html("<script>ok(scriptorder++ == 0, 'Script is executed in order');ok($('#scriptorder').length == 0,'Execute before html')<\/script><span id='scriptorder'><script>ok(scriptorder++ == 1, 'Script is executed in order');ok($('#scriptorder').length == 1,'Execute after html')<\/script></span><script>ok(scriptorder++ == 2, 'Script is executed in order');ok($('#scriptorder').length == 1,'Execute after html')<\/script>");
setTimeout( start, 100 ); setTimeout( start, 100 );
}); });