0

My problem is that - I have this HTML code

<header>
  <h1>Javascript Events</h1>
</header>
<main>
  <ul id="checklist">
    <li>
      <span>Apples</span>
      <input value="Apples" />
    </li>
    <li><span>Oranges</span>
      <input value="Oranges" />
    </li>
    <li><span>Bananas</span>
      <input value="Bananas" />
    </li>
  </ul>
</main>

My intention is to add an EventListener to every "li" and "input" element.

I am able to do that with for loop

let checklist = document.getElementById("checklist");

let items = checklist.querySelectorAll("li");
let inputs = checklist.querySelectorAll("input");

for(let i = 0; i<lists.length; i++){
  items[i].addEventListener("click", Open)
  inputs[i].addEventListener("blur", Change)
  inputs[i].addEventListener("keypress", Great)
 }

So I decided to try to do the same thing with forEach and that is my idea:

items.forEach(x => {
 x.addEventListener("click", EditItem)
  })

inputs.forEach((x) =>{
    x.addEventListener("blur", updateItem)
    x.addEventListener("keypress", itemKeypress);
})

Unfortunately, this code is not working and I think it is because the variable "items" is not an array.

What cause my code to not work and what are potential solutions?

let checklist = document.getElementById("checklist");

let items = checklist.querySelectorAll("li");
let inputs = checklist.querySelectorAll("input");

items.forEach(x => {
  x.addEventListener("click", EditItem)
})

inputs.forEach((x) => {
  x.addEventListener("blur", updateItem)
  x.addEventListener("keypress", itemKeypress);
})

function EditItem(){ console.log('edit'); }
function updateItem(){ console.log('udpate'); }
function itemKeypress(){ console.log('keypress'); }
<header>
  <h1>Javascript Events</h1>
</header>
<main>
  <ul id="checklist">
    <li>
      <span>Apples</span>
      <input value="Apples" />
    </li>
    <li><span>Oranges</span>
      <input value="Oranges" />
    </li>
    <li><span>Bananas</span>
      <input value="Bananas" />
    </li>
  </ul>
</main>
Kaiido
  • 123,334
  • 13
  • 219
  • 285
  • 1
    it should work. – mehulmpt Mar 19 '17 at 12:08
  • Firefox and Chrome both provide `.forEach()` on their DOM collections. Not sure about the others. –  Mar 19 '17 at 12:13
  • @trincot that comment is wrong. NodeList does have a [forEach method](https://developer.mozilla.org/en-US/docs/Web/API/NodeList/forEach) since Iterators have been implemented. OP's code should work. `getElementsByClassName` returns an HTMLCollection, which doesn't have such method (because it can be live), and it makes a **big** difference. – Kaiido Mar 07 '19 at 02:26
  • 1
    @Kaido, of course; deleted my old comment. – trincot Mar 07 '19 at 05:58

1 Answers1

0

Works fine

let checklist = document.getElementById("checklist");

let items = checklist.querySelectorAll("li");
let inputs = checklist.querySelectorAll("input");

items.forEach(x => {
  x.addEventListener("click", EditItem)
});

inputs.forEach((x) => {
  x.addEventListener("blur", updateItem)
  x.addEventListener("keypress", itemKeypress);
});

function EditItem() { console.log('Edit'); }
function updateItem() { console.log('update'); }
function itemKeypress() { console.log('keypress'); }
  <ul id="checklist">
    <li>
      <span>Apples</span>
      <input value="Apples" />
    </li>
    <li><span>Oranges</span>
      <input value="Oranges" />
    </li>
    <li><span>Bananas</span>
      <input value="Bananas" />
    </li>
  </ul>
Adrian Brand
  • 20,384
  • 4
  • 39
  • 60
  • There is a close reason for Questions caused by a problem that can not be reproduced. Posting the same Snippet as in the question and stating that it works fine is not a proper answer. – Kaiido Mar 07 '19 at 04:22