diff --git a/src/event.js b/src/event.js index a4b8f6cdb..987318547 100644 --- a/src/event.js +++ b/src/event.js @@ -270,36 +270,48 @@ jQuery.event = { handle.apply( elem, data ); } - var nativeFn, nativeHandler; + var parent = elem.parentNode || elem.ownerDocument; + + // Trigger an inline bound script try { if ( !(elem && elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()]) ) { - nativeFn = elem[ type ]; - nativeHandler = elem[ "on" + type ]; + if ( elem[ "on" + type ] && elem[ "on" + type ].apply( elem, data ) === false ) { + event.result = false; + } } + // prevent IE from throwing an error for some elements with some event types, see #3533 } catch (e) {} - var isClick = jQuery.nodeName(elem, "a") && type === "click"; + if ( !event.isPropagationStopped() && parent ) { + jQuery.event.trigger( event, data, parent, true ); - // Trigger the native events (except for clicks on links) - if ( !bubbling && nativeFn && !event.isDefaultPrevented() && !isClick ) { - this.triggered = true; - try { - elem[ type ](); - // prevent IE from throwing an error for some hidden elements - } catch (e) {} + } else if ( !event.isDefaultPrevented() ) { + var target = event.target, old, + isClick = jQuery.nodeName(target, "a") && type === "click"; - // Handle triggering native .onfoo handlers - } else if ( nativeHandler && elem[ "on" + type ].apply( elem, data ) === false ) { - event.result = false; - } + if ( !isClick && !(target && target.nodeName && jQuery.noData[target.nodeName.toLowerCase()]) ) { + try { + if ( target[ type ] ) { + // Make sure that we don't accidentally re-trigger the onFOO events + old = target[ "on" + type ]; - this.triggered = false; + if ( old ) { + target[ "on" + type ] = null; + } - if ( !event.isPropagationStopped() ) { - var parent = elem.parentNode || elem.ownerDocument; - if ( parent ) { - jQuery.event.trigger( event, data, parent, true ); + this.triggered = true; + target[ type ](); + } + + // prevent IE from throwing an error for some elements with some event types, see #3533 + } catch (e) {} + + if ( old ) { + target[ "on" + type ] = old; + } + + this.triggered = false; } } }, diff --git a/test/unit/event.js b/test/unit/event.js index 99ed41936..df01baeac 100644 --- a/test/unit/event.js +++ b/test/unit/event.js @@ -394,7 +394,7 @@ test("trigger() bubbling", function() { }); test("trigger(type, [data], [fn])", function() { - expect(12); + expect(14); var handler = function(event, a, b, c) { equals( event.type, "click", "check passed data" ); @@ -439,6 +439,34 @@ test("trigger(type, [data], [fn])", function() { pass = false; } ok( pass, "Trigger on a table with a colon in the even type, see #3533" ); + + var form = jQuery("
").appendTo("body"); + + // Make sure it can be prevented locally + form.submit(function(){ + ok( true, "Local bind still works." ); + return false; + }); + + // Trigger 1 + form.trigger("submit"); + + form.unbind("submit"); + + jQuery(document).submit(function(){ + ok( true, "Make sure bubble works up to document." ); + return false; + }); + + // Trigger 1 + form.trigger("submit"); + + jQuery(document).unbind("submit"); + + form.remove(); +}); + +test("jQuery.Event.currentTarget", function(){ }); test("trigger(eventObject, [data], [fn])", function() {