From: jeresig Date: Thu, 28 Jan 2010 20:25:52 +0000 (-0500) Subject: Further optimize the empty/remove/cleanData logic. X-Git-Url: http://git.asbjorn.biz/?p=jquery.git;a=commitdiff_plain;h=98c7248518f9a2082ccf50240b5ab44bf98d7b5e Further optimize the empty/remove/cleanData logic. --- diff --git a/src/data.js b/src/data.js index 0049a9f..20c134a 100644 --- a/src/data.js +++ b/src/data.js @@ -132,3 +132,22 @@ jQuery.fn.extend({ }); } }); + +var removeExpando = function( elem ) { + delete elem[ expando ]; +}; + +try { + var div = document.createElement("div"); + div[ expando ] = true; + delete div[ expando ]; + +} catch( e ) { + // IE has trouble directly removing the expando + // but it's ok with using removeAttribute + removeExpando = function( elem ) { + if ( elem.removeAttribute ) { + elem.removeAttribute( expando ); + } + }; +} \ No newline at end of file diff --git a/src/event.js b/src/event.js index 602332f..b4650ae 100644 --- a/src/event.js +++ b/src/event.js @@ -221,11 +221,7 @@ jQuery.event = { if ( !ret ) { if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) { - if ( elem.removeEventListener ) { - elem.removeEventListener( type, elemData.handle, false ); - } else if ( elem.detachEvent ) { - elem.detachEvent( "on" + type, elemData.handle ); - } + removeEvent( elem, type, elemData.handle ); } ret = null; @@ -529,6 +525,14 @@ jQuery.event = { } }; +var removeEvent = document.removeEventListener ? + function( elem, type, handle ) { + elem.removeEventListener( type, handle, false ); + } : + function( elem, type, handle ) { + elem.detachEvent( "on" + type, handle ); + }; + jQuery.Event = function( src ) { // Allow instantiation without the 'new' keyword if ( !this.preventDefault ) { diff --git a/src/manipulation.js b/src/manipulation.js index 8c188c2..ed049de 100644 --- a/src/manipulation.js +++ b/src/manipulation.js @@ -148,6 +148,40 @@ jQuery.fn.extend({ return set; } }, + + // keepData is for internal use only--do not document + remove: function( selector, keepData ) { + for ( var i = 0, elem; (elem = this[i]) != null; i++ ) { + if ( !selector || jQuery.filter( selector, [ elem ] ).length ) { + if ( !keepData && elem.nodeType === 1 ) { + jQuery.cleanData( elem.getElementsByTagName("*") ); + jQuery.cleanData( [ elem ] ); + } + + if ( elem.parentNode ) { + elem.parentNode.removeChild( elem ); + } + } + } + + return this; + }, + + empty: function() { + for ( var i = 0, elem; (elem = this[i]) != null; i++ ) { + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( elem.getElementsByTagName("*") ); + } + + // Remove any remaining nodes + while ( elem.firstChild ) { + elem.removeChild( elem.firstChild ); + } + } + + return this; + }, clone: function( events ) { // Do the clone @@ -391,38 +425,6 @@ jQuery.each({ }; }); -jQuery.each({ - // keepData is for internal use only--do not document - remove: function( selector, keepData ) { - if ( !selector || jQuery.filter( selector, [ this ] ).length ) { - if ( !keepData && this.nodeType === 1 ) { - jQuery.cleanData( this.getElementsByTagName("*") ); - jQuery.cleanData( [ this ] ); - } - - if ( this.parentNode ) { - this.parentNode.removeChild( this ); - } - } - }, - - empty: function() { - // Remove element nodes and prevent memory leaks - if ( this.nodeType === 1 ) { - jQuery.cleanData( this.getElementsByTagName("*") ); - } - - // Remove any remaining nodes - while ( this.firstChild ) { - this.removeChild( this.firstChild ); - } - } -}, function( name, fn ) { - jQuery.fn[ name ] = function() { - return this.each( fn, arguments ); - }; -}); - jQuery.extend({ clean: function( elems, context, fragment, scripts ) { context = context || document; @@ -519,9 +521,24 @@ jQuery.extend({ }, cleanData: function( elems ) { - for ( var i = 0, elem, id; (elem = elems[i]) != null; i++ ) { - jQuery.event.remove( elem ); - jQuery.removeData( elem ); + var data, id, cache = jQuery.cache; + + for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { + id = elem[ jQuery.expando ]; + + if ( id ) { + data = cache[ id ]; + + if ( data.events ) { + for ( var event in data.events ) { + removeEvent( elem, event, data.handle ); + } + } + + removeExpando( elem ); + + delete cache[ id ]; + } } } });