X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;ds=sidebyside;f=src%2Fevent.js;h=2bb8a0edc8f608ca2440722fa7fdcb9cd8b13919;hb=255068da33e3d131b3a641c041fb8cecb1543fa4;hp=2f5b1490232a09f9722eb5234f130d7db3b57cd5;hpb=9a69b2cf08f11d58ba5e53e540b96b8f4ce5072d;p=jquery.git diff --git a/src/event.js b/src/event.js index 2f5b149..2bb8a0e 100644 --- a/src/event.js +++ b/src/event.js @@ -133,7 +133,7 @@ jQuery.event = { var namespaces = type.split("."); type = namespaces.shift(); var all = !namespaces.length, - namespace = new RegExp("(^|\\.)" + namespaces.slice(0).sort().join(".*\\.") + "(\\.|$)"), + namespace = new RegExp("(^|\\.)" + namespaces.slice(0).sort().join("\\.(?:.*\\.)?") + "(\\.|$)"), special = this.special[ type ] || {}; if ( events[ type ] ) { @@ -291,7 +291,7 @@ jQuery.event = { // Cache this now, all = true means, any handler all = !namespaces.length && !event.exclusive; - var namespace = new RegExp("(^|\\.)" + namespaces.slice(0).sort().join(".*\\.") + "(\\.|$)"); + var namespace = new RegExp("(^|\\.)" + namespaces.slice(0).sort().join("\\.(?:.*\\.)?") + "(\\.|$)"); handlers = ( jQuery.data(this, "events") || {} )[ event.type ]; @@ -517,6 +517,14 @@ var withinElement = function( event ) { // handle event if we actually just moused on to a non sub-element jQuery.event.handle.apply( this, arguments ); } + +}, + +// In case of event delegation, we only need to rename the event.type, +// liveHandler will take care of the rest. +delegate = function( event ) { + event.type = event.data; + jQuery.event.handle.apply( this, arguments ); }; // Create mouseenter and mouseleave events @@ -525,11 +533,11 @@ jQuery.each({ mouseout: "mouseleave" }, function( orig, fix ) { jQuery.event.special[ fix ] = { - setup: function(){ - jQuery.event.add( this, orig, withinElement, fix ); + setup: function(data){ + jQuery.event.add( this, orig, data && data.selector ? delegate : withinElement, fix ); }, - teardown: function(){ - jQuery.event.remove( this, orig, withinElement ); + teardown: function(data){ + jQuery.event.remove( this, orig, data && data.selector ? delegate : withinElement ); } }; }); @@ -584,16 +592,18 @@ jQuery.each({ event.special[orig] = { setup:function() { - if ( this.addEventListener ) + if ( this.addEventListener ) { this.addEventListener( orig, handle, true ); - else + } else { event.add( this, fix, ieHandler ); + } }, teardown:function() { - if ( this.removeEventListener ) + if ( this.removeEventListener ) { this.removeEventListener( orig, handle, true ); - else + } else { event.remove( this, fix, ieHandler ); + } } }; }); @@ -685,13 +695,14 @@ jQuery.fn.extend({ return this.click( jQuery.event.proxy( fn, function( event ) { // Figure out which function to execute - this.lastToggle = ( this.lastToggle || 0 ) % i; + var lastToggle = ( jQuery.data( this, 'lastToggle' + fn.guid ) || 0 ) % i; + jQuery.data( this, 'lastToggle' + fn.guid, lastToggle + 1 ); // Make sure that clicks stop event.preventDefault(); // and execute the function - return args[ this.lastToggle++ ].apply( this, arguments ) || false; + return args[ lastToggle ].apply( this, arguments ) || false; })); }, @@ -742,9 +753,17 @@ function liveHandler( event ) { jQuery.each( jQuery.data( this, "events" ).live || [], function( i, fn ) { if ( fn.live === event.type ) { - var elem = jQuery( event.target ).closest( fn.selector, event.currentTarget )[0]; + var elem = jQuery( event.target ).closest( fn.selector, event.currentTarget )[0], + related; if ( elem ) { - elems.push({ elem: elem, fn: fn, closer: jQuery.lastCloser }); + // Those two events require additional checking + if ( fn.live === "mouseenter" || fn.live === "mouseleave" ) { + related = jQuery( event.relatedTarget ).closest( fn.selector )[0]; + } + + if ( !related || related !== elem ) { + elems.push({ elem: elem, fn: fn }); + } } } }); @@ -775,6 +794,10 @@ jQuery.extend({ ready: function() { // Make sure that the DOM is not already loaded if ( !jQuery.isReady ) { + if ( !document.body ) { + return setTimeout( jQuery.ready, 13 ); + } + // Remember that the DOM is ready jQuery.isReady = true; @@ -799,7 +822,7 @@ jQuery.extend({ var readyBound = false; function bindReady() { - if ( readyBound ) return; + if ( readyBound ) { return; } readyBound = true; // Catch cases where $(document).ready() is called after the @@ -822,32 +845,39 @@ function bindReady() { // maybe late but safe also for iframes document.attachEvent("onreadystatechange", function() { // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). - if ( document.readyState === "complete" && document.body ) { + if ( document.readyState === "complete" ) { document.detachEvent( "onreadystatechange", arguments.callee ); jQuery.ready(); } }); - // If IE and not an iframe + // If IE and not a frame // continually check to see if the document is ready - // NOTE: DO NOT CHANGE TO ===, FAILS IN IE. - if ( document.documentElement.doScroll && window == window.top ) (function() { - if ( jQuery.isReady ) { - return; - } + var toplevel = false; - try { - // If IE is used, use the trick by Diego Perini - // http://javascript.nwbox.com/IEContentLoaded/ - document.documentElement.doScroll("left"); - } catch( error ) { - setTimeout( arguments.callee, 0 ); - return; - } + try { + toplevel = window.frameElement == null; + } catch(e){} - // and execute any waiting functions - jQuery.ready(); - })(); + if ( document.documentElement.doScroll && toplevel ) { + (function() { + if ( jQuery.isReady ) { + return; + } + + try { + // If IE is used, use the trick by Diego Perini + // http://javascript.nwbox.com/IEContentLoaded/ + document.documentElement.doScroll("left"); + } catch( error ) { + setTimeout( arguments.callee, 0 ); + return; + } + + // and execute any waiting functions + jQuery.ready(); + })(); + } } // A fallback to window.onload, that will always work