From d12e8a34e6d96f98ac4f9408a0d61a9ed373f917 Mon Sep 17 00:00:00 2001 From: John Resig Date: Fri, 9 Jan 2009 22:10:42 +0000 Subject: [PATCH] Made it so that you can bind a single function to multiple .live() selectors. Additionally, simplified the proxy code to provide a default proxy function. Fixes #3787. --- src/event.js | 16 +++++++++------- test/unit/event.js | 27 ++++++++++++++++++++++++++- 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/src/event.js b/src/event.js index 06a6d83..405e19f 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; @@ -334,6 +331,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 @@ -362,7 +360,7 @@ jQuery.event = { remove++; }); - if ( remove <= 1 ) + if ( remove < 1 ) jQuery.event.remove( this, namespaces[0], liveHandler ); } } @@ -546,12 +544,16 @@ jQuery.fn.extend({ }, live: function( type, fn ){ - jQuery(document).bind( liveConvert(type, this.selector), this.selector, fn ); + var proxy = jQuery.event.proxy( fn ); + proxy.guid += this.selector; + + jQuery(document).bind( liveConvert(type, this.selector), this.selector, proxy ); + return this; }, die: function( type, fn ){ - jQuery(document).unbind( liveConvert(type, this.selector), fn ); + jQuery(document).unbind( liveConvert(type, this.selector), fn ? { guid: fn.guid + this.selector } : null ); return this; } }); diff --git a/test/unit/event.js b/test/unit/event.js index fb08a2e..cbeb9ff 100644 --- a/test/unit/event.js +++ b/test/unit/event.js @@ -474,7 +474,7 @@ test("toggle(Function, Function, ...)", function() { }); test(".live()/.die()", function() { - expect(30); + expect(34); var submit = 0, div = 0, livea = 0, liveb = 0; @@ -550,6 +550,31 @@ test(".live()/.die()", function() { jQuery("#anchor2").trigger("click"); equals( window.location.hash, hash, "e.preventDefault() worked" ); jQuery("#anchor2").die("click"); + + // Test binding the same handler to multiple points + var called = 0; + function callback(){ called++; return false; } + + jQuery("#nothiddendiv").live("click", callback); + jQuery("#anchor2").live("click", callback); + + jQuery("#nothiddendiv").trigger("click"); + equals( called, 1, "Verify that only one click occurred." ); + + jQuery("#anchor2").trigger("click"); + equals( called, 2, "Verify that only one click occurred." ); + + // Make sure that only one callback is removed + jQuery("#anchor2").die("click", callback); + + jQuery("#nothiddendiv").trigger("click"); + equals( called, 3, "Verify that only one click occurred." ); + + jQuery("#anchor2").trigger("click"); + equals( called, 3, "Verify that only one click occurred." ); + + // Cleanup + jQuery("#nothiddendiv").die("click", callback); }); /* -- 1.7.10.4