X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=src%2Fevent.js;h=4a0a412278ea03a1e4f2f1f232e5896cbf477df7;hb=f8ef75eb9124ce924be5fb521c783efd5c996e33;hp=06a6d831af9d82578e0f5997e3cd011eba775110;hpb=6898cd6d2a8d515941032ddb806d3cbabd2d2506;p=jquery.git diff --git a/src/event.js b/src/event.js index 06a6d83..4a0a412 100644 --- a/src/event.js +++ b/src/event.js @@ -26,10 +26,7 @@ jQuery.event = { var fn = handler; // Create unique handler function, wrapped around original handler - handler = this.proxy( fn, function() { - // Pass arguments and context to original handler - return fn.apply(this, arguments); - }); + handler = this.proxy( fn ); // Store data in unique handler handler.data = data; @@ -59,7 +56,7 @@ jQuery.event = { // Get the current list of functions bound to this event var handlers = events[type]; - + if ( jQuery.event.specialAll[type] ) jQuery.event.specialAll[type].setup.call(elem, data, namespaces); @@ -119,7 +116,7 @@ jQuery.event = { // Namespaced event handlers var namespaces = type.split("."); type = namespaces.shift(); - var namespace = RegExp("(^|\\.)" + namespaces.slice().sort().join(".*\\.") + "(\\.|$)"); + var namespace = new RegExp("(^|\\.)" + namespaces.slice().sort().join(".*\\.") + "(\\.|$)"); if ( events[type] ) { // remove the given handler for the given type @@ -132,7 +129,7 @@ jQuery.event = { // Handle the removal of namespaced events if ( namespace.test(events[type][handle].type) ) delete events[type][handle]; - + if ( jQuery.event.specialAll[type] ) jQuery.event.specialAll[type].teardown.call(elem, namespaces); @@ -199,11 +196,11 @@ jQuery.event = { // don't do events on text and comment nodes if ( !elem || elem.nodeType == 3 || elem.nodeType == 8 ) return undefined; - + // Clean up in case it is reused event.result = undefined; event.target = elem; - + // Clone the incoming data, if any data = jQuery.makeArray(data); data.unshift( event ); @@ -243,6 +240,7 @@ jQuery.event = { var all, handlers; event = arguments[0] = jQuery.event.fix( event || window.event ); + event.currentTarget = this; // Namespaced event handlers var namespaces = event.type.split("."); @@ -250,8 +248,8 @@ jQuery.event = { // Cache this now, all = true means, any handler all = !namespaces.length && !event.exclusive; - - var namespace = RegExp("(^|\\.)" + namespaces.slice().sort().join(".*\\.") + "(\\.|$)"); + + var namespace = new RegExp("(^|\\.)" + namespaces.slice().sort().join(".*\\.") + "(\\.|$)"); handlers = ( jQuery.data(this, "events") || {} )[event.type]; @@ -334,6 +332,7 @@ jQuery.event = { }, proxy: function( fn, proxy ){ + proxy = proxy || function(){ return fn.apply(this, arguments); }; // Set the guid of unique handler to the same of original handler, so it can be removed proxy.guid = fn.guid = fn.guid || proxy.guid || this.guid++; // So proxy can be declared as an argument @@ -347,7 +346,7 @@ jQuery.event = { teardown: function() {} } }, - + specialAll: { live: { setup: function( selector, namespaces ){ @@ -355,14 +354,14 @@ jQuery.event = { }, teardown: function( namespaces ){ if ( namespaces.length ) { - var remove = 0, name = RegExp("(^|\\.)" + namespaces[0] + "(\\.|$)"); - + var remove = 0, name = new RegExp("(^|\\.)" + namespaces[0] + "(\\.|$)"); + jQuery.each( (jQuery.data(this, "events").live || {}), function(){ if ( name.test(this.type) ) remove++; }); - - if ( remove <= 1 ) + + if ( remove < 1 ) jQuery.event.remove( this, namespaces[0], liveHandler ); } } @@ -374,19 +373,19 @@ jQuery.Event = function( src ){ // Allow instantiation without the 'new' keyword if( !this.preventDefault ) return new jQuery.Event(src); - + // Event object if( src && src.type ){ this.originalEvent = src; this.type = src.type; - this.timeStamp = src.timeStamp; // Event type }else this.type = src; - if( !this.timeStamp ) - this.timeStamp = now(); - + // timeStamp is buggy for some events on Firefox(#3843) + // So we won't rely on the native value + this.timeStamp = now(); + // Mark it as fixed this[expando] = true; }; @@ -442,7 +441,7 @@ var withinElement = function(event) { while ( parent && parent != this ) try { parent = parent.parentNode; } catch(e) { parent = this; } - + if( parent != this ){ // set the correct event type event.type = event.data; @@ -450,9 +449,9 @@ var withinElement = function(event) { jQuery.event.handle.apply( this, arguments ); } }; - -jQuery.each({ - mouseover: 'mouseenter', + +jQuery.each({ + mouseover: 'mouseenter', mouseout: 'mouseleave' }, function( orig, fix ){ jQuery.event.special[ fix ] = { @@ -462,7 +461,7 @@ jQuery.each({ teardown: function(){ jQuery.event.remove( this, orig, withinElement ); } - }; + }; }); jQuery.fn.extend({ @@ -501,7 +500,7 @@ jQuery.fn.extend({ event.stopPropagation(); jQuery.event.trigger( event, data, this[0] ); return event.result; - } + } }, toggle: function( fn ) { @@ -544,29 +543,45 @@ jQuery.fn.extend({ return this; }, - + live: function( type, fn ){ - jQuery(document).bind( liveConvert(type, this.selector), this.selector, fn ); + var proxy = jQuery.event.proxy( fn ); + proxy.guid += this.selector + type; + + jQuery( this.context ).bind( liveConvert(type, this.selector), this.selector, proxy ); + return this; }, - + die: function( type, fn ){ - jQuery(document).unbind( liveConvert(type, this.selector), fn ); + jQuery( this.context ).unbind( liveConvert(type, this.selector), fn ? { guid: fn.guid + this.selector + type } : null ); return this; } }); function liveHandler( event ){ - var check = RegExp("(^|\\.)" + event.type + "(\\.|$)"), - stop = true; + var check = new RegExp("(^|\\.)" + event.type + "(\\.|$)"), + stop = true, + elems = []; jQuery.each(jQuery.data(this, "events").live || [], function(i, fn){ - if ( !event.isImmediatePropagationStopped() && check.test(fn.type) ) { + if ( check.test(fn.type) ) { var elem = jQuery(event.target).closest(fn.data)[0]; - if ( elem && fn.call(elem, event, fn.data) === false ) - stop = false; + if ( elem ) + elems.push({ elem: elem, fn: fn }); } }); + + elems.sort(function(a,b) { + return jQuery.data(a.elem, "closest") - jQuery.data(b.elem, "closest"); + }); + + jQuery.each(elems, function(){ + event.currentTarget = this.elem; + if ( this.fn.call(this.elem, event, this.fn.data) === false ) + return (stop = false); + }); + return stop; } @@ -628,7 +643,7 @@ function bindReady(){ // If IE and not an iframe // continually check to see if the document is ready - if ( document.documentElement.doScroll && !window.frameElement ) (function(){ + if ( document.documentElement.doScroll && window == window.top ) (function(){ if ( jQuery.isReady ) return; try { @@ -662,9 +677,12 @@ jQuery.each( ("blur,focus,load,resize,scroll,unload,click,dblclick," + // Prevent memory leaks in IE // And prevent errors on refresh with events like mouseover in other browsers // Window isn't included so as not to unbind existing unload events -jQuery( window ).bind( 'unload', function(){ +// More info: +// - http://isaacschlueter.com/2006/10/msie-memory-leaks/ +// - https://bugzilla.mozilla.org/show_bug.cgi?id=252542 +jQuery( window ).bind( 'unload', function(){ for ( var id in jQuery.cache ) // Skip the window if ( id != 1 && jQuery.cache[ id ].handle ) jQuery.event.remove( jQuery.cache[ id ].handle.elem ); -}); +});