Further optimize the empty/remove/cleanData logic.
authorjeresig <jeresig@gmail.com>
Thu, 28 Jan 2010 20:25:52 +0000 (15:25 -0500)
committerjeresig <jeresig@gmail.com>
Thu, 28 Jan 2010 20:25:52 +0000 (15:25 -0500)
src/data.js
src/event.js
src/manipulation.js

index 0049a9f..20c134a 100644 (file)
@@ -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
index 602332f..b4650ae 100644 (file)
@@ -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 ) {
index 8c188c2..ed049de 100644 (file)
@@ -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 ];
+                       }
                }
        }
 });