Home > Back-end >  Best way to avoid repeating code when using addEventListener and functions
Best way to avoid repeating code when using addEventListener and functions

Time:12-12

im pretty new at coding, currently studing front end dev. I´m on my 5:th week learning JS and got a challange to create a toDo list with Typescript.

When i create a task in my app it has a checkbox and a "trash"-button. The idéa of the trash button is pretty clear and the checkbox is going put the task last in the list when its "checked".

I noticed some repetative code while creating my event listeners. So I found a way to add the event listener to multiple elements but I can't wrap my head around how to call the different functions that corresponds to what was clicked.

this is how I found a way to add the event listener to each element. But from here, how can I call a function based on what was clicked?

    document.querySelectorAll('.add-click-listener').forEach(item => {
        item.addEventListener('click',  event => {

        })
    })

this was the code from the beginning

    let checkbox = Array.from(document.querySelectorAll('.hidden-checkbox'));
    checkbox.forEach((item) => {
        item.addEventListener('click', checkboxStatusShift);
    });
    
    let trashBtn = Array.from(document.querySelectorAll('.trash-btn')); 
    trashBtn.forEach((item) => {
        item.addEventListener('click', deleteTask);
    });

this will be the function to "trash" a task:

function deleteTask(event: any) {
    const index = (event.currentTarget);
    const buttonId = index.id?.replace('remove-', '');
    const currentTask = todoDatabase.filter((object) => object.id === buttonId)[0];
    const currentTaskId = currentTask.id;
  
    console.log(buttonId);
    console.log(currentTaskId);
    

    if (buttonId == currentTaskId) {
        todoDatabase.splice(0, 1);
        printTodoList();
    }

}   

I haven't started the code for the checkbox function yet.

Very grateful for any tips I can get.

CodePudding user response:

From my experience, you can avoid repeating code by using an event delegation pattern. You have to attach an event listener to the parent element, and then inside the handler to check if it matches your child element. The event by clicking on child will bubble so you will catch it. In code it will look like this:

document.querySelector('#parent-element').addEventListener('click', function(e) {
  if (e.target && e.target.matches('.child-element')) {
    // do your stuff here
  }
});

CodePudding user response:

You can bind to the root element where the checkboxes are located and handle the target element that fired the event.

If the HTML looks like this:

<div id="app">
  <div >
    <input id="1" type="checkbox" /><label for="1">Checkbox 1</label>
    <input id="2" type="checkbox" /><label for="2">Checkbox 2</label>
    <input id="3" type="checkbox" /><label for="3">Checkbox 3</label>
  </div>
</div>

An example JS code could be as shown below:

const root = document.getElementsByClassName('checkboxes')[0];
root.addEventListener('click', function (event) {
  const target = event.target;

  if (target.tagName == 'INPUT') {
    console.log(target.id);
    console.log(target.checked);
  }
});

Bind a click event to the root div with the class name "checkboxes" and handle who exactly fires the event.

If you can use Jquery then the same can be done with on function https://api.jquery.com/on

$(div.checkboxes).on("click", ".checkbox", function(event){})
  • Related