17

What is the native implementation for event delegation on dynamically created dom elements?

I tried looking at the jQuery source but I can't follow the .on method.

Note: Currently I attach the event handlers after the dom elements are created, which seems pretty standard but I like the way jQuery .on handles dynamically created elements events with this syntax $( document ).on( "click", ".selector", handler );.

Brian Tompsett - 汤莱恩
  • 5,195
  • 62
  • 50
  • 120
Scott Mitchell
  • 660
  • 4
  • 11
  • Possible duplicate of http://stackoverflow.com/questions/1687296/what-is-dom-event-delegation – Greg Burghardt Aug 11 '14 at 16:53
  • Not a useful post already viewed that. It has outdated link references and no clear examples of what I'm trying to figure out. I know what event delegation is I want to know an example of how to do it natively – Scott Mitchell Aug 11 '14 at 16:54
  • On the contrary, the question is still relevant. The highest rated answer does give you an example. Could you clarify your question then? From the question I thought you wanted to know about event delegation using plain old JavaScript. – Greg Burghardt Aug 11 '14 at 16:57
  • Sorry I shouldn't say unuseful..it was useful. I was looking for more of a direct translation of the .on jquery method ( delegation protion ) to native if that exists in a "simple" form. – Scott Mitchell Aug 11 '14 at 17:02
  • @GregBurghardt: It's not a duplicate, because it doesn't ask for a native implementation, but it's a good introduction to understand what event delegation is about. – Bergi Aug 11 '14 at 17:06
  • Possible duplicate of [Modify \`target\` of mouseEvent object for Event Delegation](http://stackoverflow.com/questions/28997983/modify-target-of-mouseevent-object-for-event-delegation) – Paul Sweatte Dec 28 '16 at 14:41

5 Answers5

26

What happens is basically this:

// $(document).on("click", <selector>, handler)
document.addEventListener("click", function(e) {
    for (var target=e.target; target && target!=this; target=target.parentNode) {
    // loop parent nodes from the target to the delegation node
        if (target.matches(<selector>)) {
            handler.call(target, e);
            break;
        }
    }
}, false);

However, e.currentTarget is document when the handler is called, and e.stop[Immediate]Propagation() will work differently. jQuery abstracts over that (including call order) a lot.

I've used the .matches() method, which is not yet standard but already available under different names in modern browsers. You might use a custom predicate to test elements instead of a selector. And addEventListener is obviously not oldIE-compatible.

Bergi
  • 513,640
  • 108
  • 821
  • 1,164
  • So lets say I had a list (ul) and items (li) which are being added dynamically. I'd add an event listener to the ul using this approach and subsequent lis that were generated would run the handler? – Scott Mitchell Aug 11 '14 at 17:02
  • Yes, because it's not the `
  • ` that runs the `handler` but the listener that you've attached to the `
      ` - to which any event in the list bubbles.
  • – Bergi Aug 11 '14 at 17:05