if (!element.$handle)
element.$handle = function() {
- jQuery.event.handle.apply(element, arguments);
+ // returned undefined or false
+ var val;
+
+ // Handle the second event of a trigger and when
+ // an event is called after a page has unloaded
+ if ( typeof jQuery == "undefined" || jQuery.event.triggered )
+ return val;
+
+ val = jQuery.event.handle.apply(element, arguments);
+
+ return val;
};
// Get the current list of functions bound to this event
// Remember the function in a global list (for triggering)
if (!this.global[type])
this.global[type] = [];
- this.global[type].push( element );
+ // Only add the element to the global list once
+ if (jQuery.inArray(element, this.global[type]) == -1)
+ this.global[type].push( element );
},
guid: 1,
// Detach an event or set of events from an element
remove: function(element, type, handler) {
- var events = element.$events, ret;
+ var events = element.$events, ret, index;
if ( events ) {
// type is actually an event object here
element.detachEvent("on" + type, element.$handle);
ret = null;
delete events[type];
+
+ // Remove element from the global event type cache
+ while ( this.global[type] && ( (index = jQuery.inArray(element, this.global[type])) >= 0 ) )
+ delete this.global[type][index];
}
}
data.unshift( this.fix({ type: type, target: element }) );
// Trigger the event
- if ( (val = this.handle.apply( element, data )) !== false )
+ if ( jQuery.isFunction(element.$handle) && (val = element.$handle.apply( element, data )) !== false )
this.triggered = true;
if ( fn && val !== false && !jQuery.nodeName(element, 'a') )
handle: function(event) {
// returned undefined or false
var val;
-
- // Handle the second event of a trigger and when
- // an event is called after a page has unloaded
- if ( typeof jQuery == "undefined" || jQuery.event.triggered )
- return val;
// Empty object is for triggered events with no data
event = jQuery.event.fix( event || window.event || {} );
* data as the second parameter (and the handler function as the third), see
* second example.
*
+ * Calling bind with an event type of "unload" will automatically
+ * use the one method instead of bind to prevent memory leaks.
+ *
* @example $("p").bind("click", function(){
* alert( $(this).text() );
* });
* @cat Events
*/
bind: function( type, data, fn ) {
- return this.each(function(){
+ return type == "unload" ? this.one(type, data, fn) : this.each(function(){
jQuery.event.add( this, type, fn || data, fn && data );
});
},
document.removeEventListener( "DOMContentLoaded", jQuery.ready, false );
// Remove script element used by IE hack
- jQuery(window).load(function(){ jQuery("#__ie_init").remove(); });
+ if( !window.frames.length ) // don't remove if frames are present (#1187)
+ jQuery(window).load(function(){ jQuery("#__ie_init").remove(); });
}
}
});
var els = global[type], i = els.length;
if ( i && type != 'unload' )
do
- jQuery.event.remove(els[i-1], type);
+ els[i-1] && jQuery.event.remove(els[i-1], type);
while (--i);
}
});