-1

I am getting this error on line 42 of my js(attaching code). Please help. I am a newbie at js

let nums = document.getElementsByClassName("grid-items");
var i = 0,
  num = 0;
for (i = 0; i < nums.length; i++) {
  console.log(nums[i]);
  nums[i].addEventListener("click", function() {
    num = nums[i].innerHTML;
    console.log(num);
  })
}
<button class="grid-items" id="number0">0</button>
<button class="grid-items" id="number1">1</button>
<button class="grid-items" id="number2">2</button>
<button class="grid-items" id="number3">3</button>
<button class="grid-items" id="number4">4</button>
<button class="grid-items" id="number5">5</button>
<button class="grid-items" id="number6">6</button>
<button class="grid-items" id="number7">7</button>
<button class="grid-items" id="number8">8</button>
<button class="grid-items" id="number9">9</button>

Also, if someone has a better idea of printing the number from js on click, you can help with that. Thank you!!!!

connexo
  • 53,704
  • 14
  • 91
  • 128
vaibhavn1
  • 9
  • 4
  • All function share the same `i` which is `10` after your for-loop ends. Either use `let` and declare `i` in the for-loop `for (let i =0; ...` or use `for (const btn of document.getElementsByClassName("grid-items")) { btn.addEventListener('click', () => console.log(btn.textContent) }`. Index-based looping in most cases really is a thing from the past. – connexo Jul 10 '21 at 08:40

3 Answers3

0

you can use this:

let nums=document.getElementsByClassName("grid-items");
var i=0,num=0;
for(i=0;i<nums.length;i++){
    console.log(nums[i]);
    nums[i].addEventListener("click", function (){
        num=this.innerHTML;
        console.log(num);
    })    
}
MrOutadi
  • 52
  • 4
  • @vaibhavn1 here in an element eventListener you have access to that element by this. so you can get element innerHTML by this way, for more info about why you can read [this](https://stackoverflow.com/a/35217682/10925250) – MrOutadi Jul 09 '21 at 16:39
0

You can use forEach loop to minimize your code and make it more cleaner.

See =>

let nums = document.querySelectorAll(".grid-items");
nums.forEach(element =>{
   element.onclick = (e)=>{
     console.log(parseInt(element.textContent))
   }})

Note : I used parseInt() method to parse integer from the string returned by .innerText

connexo
  • 53,704
  • 14
  • 91
  • 128
Sanmeet
  • 1,191
  • 1
  • 7
  • 15
  • `innerText` is non-standard and should only be considered if you need its specific behaviour. Use `textContent` instead. – connexo Jul 10 '21 at 08:26
0

Your click handler uses variable i from global scope, and at the click-moment (when loop is completed) this variable points behind the array bounds, which causes an exception.

But if you make the variable i local to the loop-body, then each handler will have its own instance of i with a value specific to each iteration.

let nums = document.getElementsByClassName("grid-items")
for (let i = 0; i < nums.length; i++) {
  nums[i].addEventListener("click", function() {
    console.log(nums[i].innerHTML)
  })
}
<button class="grid-items" id="number0">0</button>
<button class="grid-items" id="number1">1</button>
<button class="grid-items" id="number2">2</button>
<button class="grid-items" id="number3">3</button>
<button class="grid-items" id="number4">4</button>
<button class="grid-items" id="number5">5</button>
<button class="grid-items" id="number6">6</button>
<button class="grid-items" id="number7">7</button>
<button class="grid-items" id="number8">8</button>
<button class="grid-items" id="number9">9</button>

Note the use of let instead of var, because var has a wider scope and won't be loop-local.

Spatz
  • 18,640
  • 7
  • 62
  • 66