Search code examples
jqueryhtmleventspropagation

Different behaviour of event bubbling for input vs a tag?


I just realized that different behaviour exists for <a> and <input> tag.

<div id="dialog">Your non-modal dialog</div>

<!--<a href="#" id="open">Open dialog</a>-->
<input id="open" value="Open dialog">
$('#open').click(function() {
    $('#dialog').dialog('open');
});

$('#dialog').dialog({
    autoOpen: false,
    modal: false
});

// Close Pop-in If the user clicks anywhere else on the page
jQuery('html') //set for html for jsfiddle, but should be 'body'
    .bind('click', function(e){
        if (jQuery('#dialog').dialog('isOpen')
            && !jQuery(e.target).is('.ui-dialog, a')
            && !jQuery(e.target).closest('.ui-dialog').length)
        {
            jQuery('#dialog').dialog('close');
            alert("close_dialog");
        }
    }
);

If using <a>, the click event is not propagated to document. If using <input>, the click event is bubbled to document, and clicking on the input directly closes the dialog. I know this can be handled with stopPropagation. The question is why <a> tags event doesn't bubble up ? Am I missing something ?

Here is a fiddle to demonstrate. Uncomment the <a> and comment the <input>, and click on it to see the differences.

Code borrowed from on Jason's answer in this question.


Solution

  • The problem lies on this line:

    && !jQuery(e.target).is('.ui-dialog, a')
    

    You are asking jQuery if the event target is an "a" tag or an element with class ".ui-dialog". Remove the "a" tag in the selector as follows and it should work as you want it to.

    && !jQuery(e.target).is('.ui-dialog')
    

    Here's the modified fiddle http://jsfiddle.net/PRQNY/1/

    P.S: Just to confirm your understanding of events. All events bubble up irrespective of the element tag in the standard DOM event model.