Bug Tracker

Opened 9 years ago

Closed 9 years ago

Last modified 8 years ago

#6359 closed bug (fixed)

live('submit') does nothing in IE if live('click') was called before. Same with delegate.

Reported by: JonathanAquino Owned by:
Priority: undecided Milestone: 1.4.3
Component: event Version: 1.4.2
Keywords: Cc:
Blocked by: Blocking:

Description

In IE, if you attach a click handler using live(), then attach a submit handler using live(), the submit handler is ignored.

However, if you attach the submit handler *before* the click handler, it works.

delegate() has the same problem.

  1. In IE7, go to http://jonathanaquino.com/jqueryLiveIssue.html
  2. Click the submit button

Expected: You see an alert dialog: "submit" Actual: You do not see an alert dialog

The code is:

<html> <head></head> <body> <form>

<input type="submit" />

</form> <a href="/jqueryLiveIssue.html">Test</a> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.js"></script> <script> $('a').live('click', function (event) {

event.preventDefault(true); alert('click');

}); $('form').live('submit', function(event) {

event.preventDefault(true); alert('submit');

}); </script> </html>

Change History (6)

comment:1 Changed 9 years ago by JonathanAquino

Here is a hack that works around the problem:

/**
 * Patch (plugin) for jQuery bug 6359: "live('submit') does nothing in IE if
 * live('click') was called before. same with delegate."
 *
 * The workaround is to ensure that live('click') calls happen *after*
 * live('submit') calls. Fixing live() fixes delegate(), which calls live().
 *
 * This plugin uses setTimeout(..., 0) to effect the workaround. That is, it
 * defers live('click') calls to a future execution context. It should work
 * around the issue in most cases.
 *
 * @author Jonathan Aquino
 * @see http://dev.jquery.com/ticket/6359
 * @see TEZLA-538
 */
(function($) {
    var originalLive = jQuery.fn.live;
    jQuery.fn.live = function(types) {
        var self = this;
        var args = arguments;
        if (types == 'click') {
            setTimeout(function() {
                originalLive.apply(self, args);
            }, 0);
        } else {
            originalLive.apply(self, args);
        }
    };
})(jQuery);

comment:2 Changed 9 years ago by bganicky

Actually it's not "ignored", just clicking the submit button doesn't worl. When you submit by hitting Enter, it works. See: http://jsbin.com/uboxu3/7/

comment:3 Changed 9 years ago by tectonic

Thanks for posting this patch.

comment:4 Changed 9 years ago by tectonic

Note, however, that this patch defers execution until the end of the currently running JavaScript execution path, which makes testing the live behavior difficult in some testing frameworks. A better solution would be great.

comment:5 Changed 9 years ago by john.firebaugh

Here's an analysis. All line numbers refer to jquery-1.4.2.js.

With both 'click' and 'submit' live-bound in that order, there are two handlers for bubbled 'click' events on the document: liveHandler for the click event and the 'click.specialSubmit' handler used to normalize submit event bubbling behavior on IE (line 2201).

liveHandler for the click event is called first and matches none of the conditions on line 2534 which would cause an early return. It then sets event.liveFired = this and continues processing.

The 'click.specialSubmit' handler is called second. It triggers a submit event on the document, passing the same event object that was passed to the first liveHandler. The event's type is set to "submit" but all other properties remain the same, including liveFired. Then liveHandler is called for the triggered submit event, but since event.liveFired === this, it returns early, and the bound function is never called.

comment:6 Changed 9 years ago by john

Priority: undecided
Resolution: fixed
Status: newclosed
Note: See TracTickets for help on using tickets.