Attach event to dynamic elements in javascript

You must attach the event after insert elements, like that you don't attach a global event on your document but a specific event on the inserted elements.

e.g.

document.getElementById('form').addEventListener('submit', function(e) {
  e.preventDefault();
  var name = document.getElementById('txtName').value;
  var idElement = 'btnPrepend';
  var html = `
    <ul>
      <li>${name}</li>
    </ul>
    <input type="button" value="prepend" id="${idElement}" />
  `;
  /* Insert the html into your DOM */
  insertHTML('form', html);
  /* Add an event listener after insert html */
  addEvent(idElement);
});

const insertHTML = (tag = 'form', html, position = 'afterend', index = 0) => {
  document.getElementsByTagName(tag)[index].insertAdjacentHTML(position, html);
}
const addEvent = (id, event = 'click') => {
  document.getElementById(id).addEventListener(event, function() {
    insertHTML('ul', '<li>Prepending data</li>', 'afterbegin')
  });
}
<form id="form">
  <div>
    <label for="txtName">Name</label>
    <input id="txtName" name="txtName" type="text" />
  </div>
  <input type="submit" value="submit" />
</form>

This is due to the fact that your element is dynamically created. You should use event delegation to handle the event.

 document.addEventListener('click',function(e){
    if(e.target && e.target.id== 'brnPrepend'){
          //do something
     }
 });

jquery makes it easier:

 $(document).on('click','#btnPrepend',function(){//do something})

Here is an article about event delegation event delegation article


The difference is in how you create and append elements in the DOM.

If you create an element via document.createElement, add an event listener, and append it to the DOM. Your events will fire.

If you create an element as a string like this: html += "<li>test</li>"`, the elment is technically just a string. Strings cannot have event listeners.

One solution is to create each element with document.createElement and then add those to a DOM element directly.

// Sample
let li = document.createElement('li')
document.querySelector('ul').appendChild(li)

There is a workaround by capturing clicks on document.body and then checking event target.

document.body.addEventListener( 'click', function ( event ) {
  if( event.target.id == 'btnSubmit' ) {
    someFunc();
  };
} );

Tags:

Javascript