Landing the new expando management code. Completely overhauls how data is associated with elements.
Plugins will be most interested in: - jQuery.data(elem) -> Unique ID for the element - jQuery.data(elem, name) -> Named data store for the element - jQuery.data(elem, name, value) -> Saves a value to the named data store - jQuery.removeData(elem) -> Remove the expando and the complete data store - jQuery.removeData(elem, name) -> Removes just this one named data store jQuery's .remove() and .empty() automatically clean up after themselves. Once an element leaves a DOM document their events are no longer intact. Thus, statements like so: {{{ $("#foo").remove().appendTo("#bar"); }}} should be written like so: {{{ $("#foo").appendTo("#bar"); }}} in order to avoid losing the bound events.
This commit is contained in:
parent
15a78f8fea
commit
3a4e1233aa
5 changed files with 108 additions and 47 deletions
75
src/core.js
75
src/core.js
|
@ -238,7 +238,7 @@ jQuery.fn = jQuery.prototype = {
|
|||
var clone = ret.find("*").andSelf();
|
||||
|
||||
this.find("*").andSelf().each(function(i) {
|
||||
var events = this.$events;
|
||||
var events = jQuery.data(this, "events");
|
||||
for ( var type in events )
|
||||
for ( var handler in events[type] )
|
||||
jQuery.event.add(clone[i], type, events[type][handler], events[type][handler].data);
|
||||
|
@ -411,6 +411,8 @@ jQuery.extend = jQuery.fn.extend = function() {
|
|||
return target;
|
||||
};
|
||||
|
||||
var expando = "jQuery" + (new Date()).getTime(), uuid = 0;
|
||||
|
||||
jQuery.extend({
|
||||
noConflict: function(deep) {
|
||||
window.$ = _$;
|
||||
|
@ -450,6 +452,58 @@ jQuery.extend({
|
|||
nodeName: function( elem, name ) {
|
||||
return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase();
|
||||
},
|
||||
|
||||
cache: {},
|
||||
|
||||
data: function( elem, name, data ) {
|
||||
var id = elem[ expando ];
|
||||
|
||||
// Compute a unique ID for the element
|
||||
if ( !id )
|
||||
id = elem[ expando ] = ++uuid;
|
||||
|
||||
// Only generate the data cache if we're
|
||||
// trying to access or manipulate it
|
||||
if ( name && !jQuery.cache[ id ] )
|
||||
jQuery.cache[ id ] = {};
|
||||
|
||||
// Prevent overriding the named cache with undefined values
|
||||
if ( data != undefined )
|
||||
jQuery.cache[ id ][ name ] = data;
|
||||
|
||||
// Return the named cache data, or the ID for the element
|
||||
return name ? jQuery.cache[ id ][ name ] : id;
|
||||
},
|
||||
|
||||
removeData: function( elem, name ) {
|
||||
var id = elem[ expando ];
|
||||
|
||||
// If we want to remove a specific section of the element's data
|
||||
if ( name ) {
|
||||
// Remove the section of cache data
|
||||
delete jQuery.cache[ id ][ name ];
|
||||
|
||||
// If we've removed all the data, remove the element's cache
|
||||
name = "";
|
||||
for ( name in jQuery.cache[ id ] ) break;
|
||||
if ( !name )
|
||||
jQuery.removeData( elem );
|
||||
|
||||
// Otherwise, we want to remove all of the element's data
|
||||
} else {
|
||||
// Clean up the element expando
|
||||
try {
|
||||
delete elem[ expando ];
|
||||
} catch(e){
|
||||
// IE has trouble directly removing the expando
|
||||
// but it's ok with using removeAttribute
|
||||
elem.removeAttribute( expando );
|
||||
}
|
||||
|
||||
// Completely remove the data cache
|
||||
delete jQuery.cache[ id ];
|
||||
}
|
||||
},
|
||||
|
||||
// args is for internal usage only
|
||||
each: function( obj, fn, args ) {
|
||||
|
@ -836,14 +890,16 @@ jQuery.extend({
|
|||
},
|
||||
|
||||
unique: function(first) {
|
||||
var r = [], num = jQuery.mergeNum++;
|
||||
var r = [], done = {};
|
||||
|
||||
try {
|
||||
for ( var i = 0, fl = first.length; i < fl; i++ )
|
||||
if ( num != first[i].mergeNum ) {
|
||||
first[i].mergeNum = num;
|
||||
for ( var i = 0, fl = first.length; i < fl; i++ ) {
|
||||
var id = jQuery.data(first[i]);
|
||||
if ( !done[id] ) {
|
||||
done[id] = true;
|
||||
r.push(first[i]);
|
||||
}
|
||||
}
|
||||
} catch(e) {
|
||||
r = first;
|
||||
}
|
||||
|
@ -851,8 +907,6 @@ jQuery.extend({
|
|||
return r;
|
||||
},
|
||||
|
||||
mergeNum: 0,
|
||||
|
||||
grep: function(elems, fn, inv) {
|
||||
// If a string is passed in for the function, make a function
|
||||
// for it (a handy shortcut)
|
||||
|
@ -977,10 +1031,15 @@ jQuery.each( {
|
|||
jQuery.className[ jQuery.className.has(this,c) ? "remove" : "add" ](this, c);
|
||||
},
|
||||
remove: function(a){
|
||||
if ( !a || jQuery.filter( a, [this] ).r.length )
|
||||
if ( !a || jQuery.filter( a, [this] ).r.length ) {
|
||||
jQuery.removeData( this );
|
||||
this.parentNode.removeChild( this );
|
||||
}
|
||||
},
|
||||
empty: function() {
|
||||
// Clean up the cache
|
||||
jQuery("*", this).each(function(){ jQuery.removeData(this); });
|
||||
|
||||
while ( this.firstChild )
|
||||
this.removeChild( this.firstChild );
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue