How can i get index use forEach loop?

Viewed 2410

I've tried to

<ul class="product">
  <li>aaaaa</li>
  <li>bbbbb</li>
  <li class="on">ccccc</li>
  <li>ddddd</li>
</ul>
const product = document.querySelector(".product");
const productList = product.querySelectorAll("li");

function getIdx() {
  productList.forEach((list, idx) => {
    let productClassList = list.classList;
    let parsedList = Array.from(productClassList);

    if (parsedList.includes("on")) {
      return idx;
    }
  });
};

function printIdx() {
  let idx = getIdx();

  console.log(idx); // Print undefined
}

productList.forEach(list => {
  list.addEventListener("click", printIdx);
});

but it is not working, it is always print "undefined" when i click content of li tag

i wanna get index when i click content of li tag and i wanna use that like web shopping site

how can i get index?

3 Answers

You can simply use a for loop and use classList.contains() to check if the class is present. Also, you need to declare a local var, to store the index returned from the loop.

const product = document.querySelector(".product");
const productList = product.querySelectorAll("li");

function getIdx() {
  let idx;
  for (var i = 0; i < productList.length; i++) {
    let list = productList[i];

    if (list.classList.contains("on")) {
      idx = i;
    }
  }
  return idx;
};

function printIdx() {
  let idx = getIdx();

  console.log(idx);
}

productList.forEach(list => {
  list.addEventListener("click", printIdx);
});
<ul class="product">
  <li>aaaaa</li>
  <li>bbbbb</li>
  <li class="on">ccccc</li>
  <li>ddddd</li>
</ul>

you just need to save the index outside the foreach loop like this:

const product = document.querySelector(".product");
const productList = product.querySelectorAll("li");

function getIdx() {
  //var for holding the correct index
  let index = -1;
  productList.forEach((list, idx) => {
    let productClassList = list.classList;
    let parsedList = Array.from(productClassList);

    if (parsedList.includes("on")) {
      //put the index we found and exit the loop
      index = idx;
      return;
    }
  });
  //return the value
  return index;
};

function printIdx() {
  let idx = getIdx();

  console.log(idx); // Print undefined
}

productList.forEach(list => {
  list.addEventListener("click", printIdx);
});
<ul class="product">
  <li>aaaaa</li>
  <li>bbbbb</li>
  <li class="on">ccccc</li>
  <li>ddddd</li>
</ul>

Well, a safer way to get all <li>s with the class "on" you could do something like the following:

[...document.querySelectorAll(".product li")]
.reduce((a,li,i)=>{
  li.onclick=()=>console.log(a);
  li.classList.contains("on")&&a.push(i)
  return a
},[]);
<ul class="product">
  <li class="one">this will not be selected</li> 
  <li>bbbbb</li>
  <li class="a on b">this will be selectd</li>
  <li class="on">and this one too!</li>
</ul>

Fun fact: in my .reduce() call I assemble the array a that will only exist in the scope of the callback function as I don't store the return value of the .reduce()-call. But within its scope a will be referenced in the event handler function for each <li>.

Related