Switched to using DOM Fragments in domManip.

This commit is contained in:
John Resig 2008-12-19 04:37:54 +00:00
parent 2875460f63
commit 132b8de614
2 changed files with 53 additions and 50 deletions

View file

@ -243,27 +243,27 @@ jQuery.fn = jQuery.prototype = {
}, },
append: function() { append: function() {
return this.domManip(arguments, true, false, function(elem){ return this.domManip(arguments, true, function(elem){
if (this.nodeType == 1) if (this.nodeType == 1)
this.appendChild( elem ); this.appendChild( elem );
}); });
}, },
prepend: function() { prepend: function() {
return this.domManip(arguments, true, true, function(elem){ return this.domManip(arguments, true, function(elem){
if (this.nodeType == 1) if (this.nodeType == 1)
this.insertBefore( elem, this.firstChild ); this.insertBefore( elem, this.firstChild );
}); });
}, },
before: function() { before: function() {
return this.domManip(arguments, false, false, function(elem){ return this.domManip(arguments, false, function(elem){
this.parentNode.insertBefore( elem, this ); this.parentNode.insertBefore( elem, this );
}); });
}, },
after: function() { after: function() {
return this.domManip(arguments, false, true, function(elem){ return this.domManip(arguments, false, function(elem){
this.parentNode.insertBefore( elem, this.nextSibling ); this.parentNode.insertBefore( elem, this.nextSibling );
}); });
}, },
@ -497,44 +497,28 @@ jQuery.fn = jQuery.prototype = {
}); });
}, },
domManip: function( args, table, reverse, callback ) { domManip: function( args, table, callback ) {
var clone = this.length > 1, elems; if ( this[0] ) {
var fragment = document.createDocumentFragment(),
scripts = jQuery.clean( args, this[0].ownerDocument, fragment ),
first = fragment.firstChild;
return this.each(function(){ if ( first )
if ( !elems ) { for ( var i = 0, l = this.length; i < l; i++ )
elems = jQuery.clean( args, this.ownerDocument ); callback.call( root(this[i], first), this.length > 1 ? fragment.cloneNode(true) : fragment );
if ( reverse ) if ( scripts )
elems.reverse(); jQuery.each( scripts, evalScript );
} }
var obj = this; return this;
if ( table && jQuery.nodeName( this, "table" ) && jQuery.nodeName( elems[0], "tr" ) ) function root( elem, cur ) {
obj = this.getElementsByTagName("tbody")[0] || this.appendChild( this.ownerDocument.createElement("tbody") ); return table && jQuery.nodeName(elem, "table") && jQuery.nodeName(cur, "tr") ?
(elem.getElementsByTagName("tbody")[0] ||
var scripts = jQuery( [] ); elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
elem;
jQuery.each(elems, function(){
var elem = clone ?
jQuery( this ).clone( true )[0] :
this;
// execute all scripts after the elements have been injected
if ( jQuery.nodeName( elem, "script" ) )
scripts = scripts.add( 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 );
} }
});
scripts.each( evalScript );
});
} }
}; };
@ -955,8 +939,8 @@ jQuery.extend({
return ret; return ret;
}, },
clean: function( elems, context ) { clean: function( elems, context, fragment ) {
var ret = []; var ret = [], scripts = [];
context = context || document; context = context || document;
// !context.createElement fails in IE with an error but returns typeof 'object' // !context.createElement fails in IE with an error but returns typeof 'object'
@ -1038,20 +1022,39 @@ jQuery.extend({
} }
if ( fragment ) {
var found = div.getElementsByTagName("script");
while ( found.length ) {
scripts.push( found[0] );
found[0].parentNode.removeChild( found[0] );
}
}
elem = jQuery.makeArray( div.childNodes ); elem = jQuery.makeArray( div.childNodes );
} }
if ( elem.length === 0 && (!jQuery.nodeName( elem, "form" ) && !jQuery.nodeName( elem, "select" )) ) if ( elem.nodeType )
return;
if ( elem[0] === undefined || jQuery.nodeName( elem, "form" ) || elem.options )
ret.push( elem ); ret.push( elem );
else else
ret = jQuery.merge( ret, elem ); ret = jQuery.merge( ret, elem );
}); });
if ( fragment ) {
for ( var i = 0; ret[i]; i++ ) {
if ( jQuery.nodeName( ret[i], "script" ) ) {
ret[i].parentNode.removeChild( ret[i] );
} else {
if ( ret[i].nodeType === 1 )
ret = jQuery.merge( ret, ret[i].getElementsByTagName("script"));
fragment.appendChild( ret[i] );
}
}
return scripts;
}
return ret; return ret;
}, },

View file

@ -258,10 +258,10 @@ test("jQuery('html')", function() {
reset(); reset();
foo = false; foo = false;
var s = jQuery("<script>var foo='test';</script>")[0]; var s = jQuery("<script>foo='test';</script>")[0];
ok( s, "Creating a script" ); ok( s, "Creating a script" );
ok( !foo, "Make sure the script wasn't executed prematurely" ); ok( !foo, "Make sure the script wasn't executed prematurely" );
jQuery("body").append(s); jQuery("body").append("<script>foo='test';</script>");
ok( foo, "Executing a scripts contents in the right context" ); ok( foo, "Executing a scripts contents in the right context" );
reset(); reset();