JavaScript

Binding Event Listeners to Dynamically Created Elements

  • JavaScript programming
    language
  • Pythonprogramming
    language
  • Javaprogramming
    language
  • PHPprogramming
    language
  • C++programming
    language
  • Rubyprogramming
    language

We have the existing <li> HTML elements that contain "programming languages" and buttons "delete". We can remove any programming language clicking "delete" button ! (Try It!)

We can add dynamically created <li> elements with "Frameworks" and buttons "delete" by "click" or "keypress" events using input value. (Try It! Enter the Framework that you know and click "Add Framework" button or press the "Enter" key!)

To create and add new <li> HTML elemenets dynamically the insertAdjacentHTML() JavaScript method was used:

const button = document.querySelector(".button-add-framework");

const input = document.querySelector("#input-value");

const ul = document.querySelector("ul");

/*Add an element at the beginning of the list by clicking "Add Framework" button:*/

button.addEventListener("click", function () {

if (input.value !== "") {

const li = `<li class="element-list"> ${input.value}<span>framework</span><button class="btn-delete">delete</button></li>`;

ul.insertAdjacentHTML( "afterBegin", li);

input.value = "";

  }

});

/*Add an element at the beginning of the list by pressing key "Enter":*/

input.addEventListener("keypress", function (e) {

if (e.key === "Enter" && input.value !== "") {

const li = `<li class="element-list"> ${input.value}<span>framework</span><button class="btn-delete">delete</button></li>`;

ul.insertAdjacentHTML("afterBegin", li);

input.value = "";

  }

});

But we can not remove added <li> element by clicking "delete" button. The problem is that an ordinary code will affect only <li> elements with "programming languages" but the dynamically created elements with "frameworks" will not be affected:

const deleteButtons = document.querySelectorAll(".btn-delete");

deleteButtons.forEach((delBtn) => {

delBtn.addEventListener("click", () => {

  delBtn.parentElement.remove();

  });

});

So, It means that we can delete only "programming languages" but not added "frameworks" by clicking "delete" button !

To solve this problem and make our new added <li> elements (with "frameworks" and "delete" buttons) clickable, we use "Event Delegation" pattern!

It means that we are adding handling of the event not directly to our <button> "delete" element but to the <ul> element that contains all <li> elements and stands above them in DOM structure. So, We are "catching" an event triggered in our <ul> element that matches our selected "delete" <button> element:

const ul = document.querySelector("ul");

ul.addEventListener("click", (event) => {

if (event.target.classList.contains ("btn-delete")) {

event.target.parentElement.remove();

  }

});

We used the classList property and the contains() method to "catch" the "click" event on the HTML element that we need: event.target.classList.contains("btn-delete") !

conclusion

Using "Event Delegation" pattern we can provide an element we need with the event handler, based on the event attached to its parent element or to the element standing higher in the DOM. It allows us to include all Dynamically Created Elements to the list of event handlers that we need !