Q:

Buttons not deleting items as intended after changing from querySelectorAll to getElementsByClassName

My little app was working before I started selecting list items using let getListObjects = document.getElementsByClassName("todoListItems") instead of let getListObjects = document.querySelectorAll('li')
Reason for this is because I am adding another UL section in the app on a seperate portion of the page and want those list items to do something else.
Long story short, I can only delete 2/3 list items in the main app, unless i delete the bottom li item first which then lets me delete all of them. It makes 0 sense to me. Below is the code.

function applyButton() { //onload for dummy data or data from db
  let getListObjects = document.getElementsByClassName("todoListItems")

  for (let i = 0; i < getListObjects.length; i++) {

    let node2 = document.createElement('a')
    let iconNode = document.createElement('i')
    let att = document.createAttribute("href");
    att.value = "#"
    node2.setAttributeNode(att)
    node2.appendChild(iconNode)
    iconNode.classList.add('far')
    iconNode.classList.add('fa-trash-alt')
    iconNode.classList.add('trashCan')


    getListObjects[i].appendChild(node2)
    //addEventToButton2(getListObjects[i]) no need for it, keeping it here as a reminder of what happens with scoping

    node2.addEventListener('click', function() {
      node2.parentNode.parentNode.removeChild(getListObjects[i])
    });

  }

}
<div>
  <ul id='list-body'>
    <li id='enterItem'><input type='text' placeholder="Enter List Item..." id='newNote' class='inputEnterItem'></li>
    <li class='todoListItems'><span>Walk Dog Hit Gym and Lift Bro Hit Gym and Lift Bro  Hit Gym and Lift Bro Hit Gym and Lift Bro</span></li>
    <li class='todoListItems'><span>Hit Gym and Lift Bro</span></li>
    <li class='todoListItems'><span>Stretch</span></li>
  </ul>
</div>

TLDR: Before I selected these LI items with querySelectorAll it worked with no bugs. Now that I select them by className it bugs out only letting me delete 2/3 of the li items or all 3 items if I delete the bottom LI first

A:

getElementsByClassName returns a live collection. If you save the collection in a variable, and then remove one of the elements in the collection from the DOM, or add another element with the same class name into the DOM, the collection will change:

const foos = document.getElementsByClassName('foo');
console.log(foos.length);
foos[0].remove();
console.log(foos.length);
<div class="foo"></div>

It's quite unintuitive, because it can mutate itself if you're doing anything that can change the collection. querySelectorAll returns a static NodeList, which is not live - an element at, for example, index 3 will remove at index 3 forever, even if removed from the DOM, unless you explicitly go in and remove it from the NodeList.
Easy solution: Use querySelectorAll instead.
To select all elements of a particular class name with querySelectorAll, put . in front of the class name: change
document.getElementsByClassName('foo');

to
document.querySelectorAll('.foo');

Another possibility would be to save a reference to the current getListObjects[i] on each iteration of the loop:
let getListObjects = document.getElementsByClassName("todoListItems")
for(let i = 0; i< getListObjects.length; i++){
  const listObject = getListObjects[i];
  // now that we have a reference to the singular element,
  // don't ever refer to the collection again:

  let node2 = document.createElement('a')
  // ...

  listObject.appendChild(node2)

  node2.addEventListener('click', function(){
    node2.parentNode.parentNode.removeChild(listObject)  
  });
}

You can also use listObject.remove() to clean up the click listener a bit, if you want:
node2.addEventListener('click', function(){
  listObject.remove();
});

