1

My code is this:

document.addEventListener('click', function(ev){
  if(ev.path[0].className == 'linkTogether'){//do something}
  if(ev.path[0].id == "createNewPage"){//do something}
});

Which has actually been working well for dynamically created buttons and nodes, but something just feels off about it. So I'm wondering if this is best practice or if there is a better way to add event listeners to dynamically created elements.

Thanks, Jack

  • 1
    So every time a click is happened anywhere in the page this code is being executed? – zerkms Apr 23 '15 at 23:52
  • 1
    There is a very detailed discussion of centralized delegated event handling vs. direct element event handling here: [Should all jquery events be bound to $(document)?](http://stackoverflow.com/questions/12824549/should-all-jquery-events-be-bound-to-document/12824698#12824698). – jfriend00 Apr 24 '15 at 00:29

3 Answers3

1

In specific cases where you have huge amount of objects that behave in the same way you can use this technique (adding event listener to their parent) to improve the performance of your script.

In a general page however you just have to many different objects and iterating trough all of them to check which one you've clicked is not faster.

Here is an article for the technique you are referring to - event delegation.

Chavdar Slavov
  • 865
  • 8
  • 22
1

This is the proper pattern for creating event listeners that will work for dynamically-added elements. It's essentially the same approach as used by jQuery's event delegation methods (e.g. .on).

However, it does have performance implications. Every time you click anywhere in the document, the code will run, and have to go through the entire list of event bindings that you need to check. You can improve this by adding your event listener to a more specific element. If the dynamic elements are always added inside a specific DIV, add your listener to that DIV rather than document.

This also avoids another pitfall of event delegation. Event delegation depends on the event bubbling up from an inner element to all its containers. But if there are any handlers along the way that call event.stopPropagation, the event won't make it out to document. If you add the listener to a lower element, you're less likely to have a conflict like that.

Barmar
  • 741,623
  • 53
  • 500
  • 612
0

And I would like to add, if you create elements dynamically, better you include the listeners inline and filter in the function what you want to do.

<div class="form_ID1" onclick="myfunction(this, event);">
... children bubbling 
... Use if statements in caught js myFunction function.

In myfunction function you will capture the child element by event.target and the element that contains the listener by this.className.

There are scenarios however that you need a universal ( document ) click event. e.g You need to close a pop up when you click outside of a pop up !! It is like: e.g.

if (clicked.className != popup.className) popup.remove()

Even in this case there is a workaround by inserting an onblur="myfunction(this); in the parent DIV of the popup.

Thanasis
  • 329
  • 4
  • 8