Reassigned NodeList in ForEach Loop with list.js

116 Views Asked by At

I'm using List.js to sort a HTML list. The JS reorders the list items in the DOM. Now I made elements in my list clickable and i need to use the (new) index of my list items.

Super Simple HTML setup:

<div id="mylist">
  <ul class="simple list">
    <li class="items">one</li>
    <li class="items">two</li>
    <li class="items">three</li>
    <li class="items">four</li>
  </ul>
</div>

JS

let nodeList = getUpdatedList();

function getUpdatedList () {
  return document.querySelectorAll('.items');
}

// here comes the List.js setup
const list = new List("mylist", { "some options" });

// and here I reassign the new List to the nodeList variable
list.on('updated', ()=>{
  nodeList = getUpdatedList();
})

// print the index on click
nodeList.forEach((item, index) => {
  item.addEventListener('click', () => {
    console.log(index);
  })
})

List.js works perfectly, the items are now reordered in the DOM after a sort method. For example

  <ul class="simple list">
    <li class="items">three</li>
    <li class="items">four</li>
    <li class="items">two</li>
    <li class="items">one</li>
  </ul>

But when I click on the first item, the console still prints 4 (the old order) although I reassigned nodelist after list.js update.

1

There are 1 best solutions below

3
nullromo On

When you do this part, you're adding an event listener to each button. The value of index is locked in at that point. Each click callback is a closure that contains its own index value.

nodeList.forEach((item, index) => {
  item.addEventListener('click', () => {
    console.log(index); // this will never change
  })
})

If you want the values to change, either re-assign the click handlers or re-write the click handler function to do some other kind of logic to check the new position.