Search code examples
javascripteventsevent-handlingdom-eventsevent-delegation

Understanding Event Delegation Handling


I am trying to use event delegation for different forms on the same page. However, I am getting an interesting problem while trying to submit the forms.

I tried 'click' on one form (intended for the submission button) knowing fully well that event delegation inherently sets 'click' on the entire form.

However the problem comes from the fact that the 'click' event is actually set on the whole page and not only the form or the button element. So wherever I click on the page, the 'click' event for the form is triggered. And this is happening for all browsers.

The same thing is happening for the 'change' event. When I set the 'change' event on the form, it is triggered for both child fields of the form, and other fields outside the particular form node.

So while I know there have been questions asked about event delegation before, they do not really answer this problem. Is it even a problem? Maybe this is how event delegation is intended to work? But if so, then is it not a waste of memory for the events to be triggered for the entire document? What is the solution?

Also, is there a cross-browser way to stop propagation in pure Javascript? The best I found was on Quirksmode.org:

function doSomething(e)
{    
    if (!e) var e = window.event;
    e.cancelBubble = true;
    if (e.stopPropagation) e.stopPropagation();
}

I know I can filter the events by type when triggered but is that the only thing one can do? Please help me understand this!

Edit:

The specific question is whether delegating an event to a form for handling events on its specific fields will/can also trigger events on the rest of the document? If so, how to handle this? And if this is not the intended behavior of event delegation, then what might be causing it?


Solution

  • An event will bubble though its ancestors. If you had the HTML structure;

    <div>
        <h2>
            <span>
                <input />
            </span>
            <strong>
                Blah
            </strong>
    

    ... and you clicked the input element, you'd see click event originate on the input element, then bubble up its ancestors (span, h2, div, body, document). It wouldn't fire on the strong, because it's not an ancestor. See http://jsfiddle.net/2QQFS/ for an example (look at the console when you click on one of the <input /> boxes.

    Your <form />s should not be nested. If you're attaching the event handler on each <form /> element, and seeing events on other form's trigger events on other forms, I'd validate your HTML (http://validator.w3.org) to make sure you haven't missed a closing tag somewhere, or something.

    To see which element the event originated from, you can use e.target, and e.srcElement (IE < 8).