0

I am trying to make a tab section whenever we click on a tab, a content appears below , i have used the code in the following codepen, but i get an error

`

Uncaught TypeError: Cannot read properties of undefined (reading 'style')

`

I don't understand what is wrong with the logic or why isn't the property style not accessible and why do i get this error whenever i click a tab.

codepen link : https://codepen.io/theSpaceWeasel/pen/XWBKdbP?editors=1111

`

var btns = document.querySelectorAll(".tablinks");
console.log(btns);
var content = document.querySelectorAll(".tabcontent");
console.log(content);

for(var i=0; i<btns.length;i++){
  btns[i].addEventListener('click', function(){
    content[i].style.display = "block";
  })
}


`

1 Answers1

0

The issue with the original code is that the content[i] element is undefined when the event listener callback function is called, because i refers to the final value of i at the end of the loop (which will always be greater).

for (var i = 0; i < btns.length; i++) {
  btns[i].addEventListener("click", (function(index) {
    return function() {
      content[index].style.display = "block";
    };
  })(i));
}

To fix this issue, you can use a closure to create a new scope for each iteration of the loop, with its own copy of the loop variable i, so that you can access the correct element of the content array when the event listener callback function is called.

Or u can simply save the the current content element in a var like

for (var i = 0; i < btns.length; i++) {
  const ele = content[i];
  btns[i].addEventListener("click", (function() {
      ele.style.display = "block";
  }));
}
uditkumar01
  • 400
  • 5
  • 11
  • with each iteration the index parameter has the same value as interation variable i? – Ray Elshobokshy Jan 01 '23 at 17:24
  • yes @RayElshobokshy index will have the value of i when the event listener was defined in the loop – uditkumar01 Jan 01 '23 at 17:26
  • this works, but now all content appear when i just want the corresponding content only to appear not all of them, thank you for your time – Ray Elshobokshy Jan 01 '23 at 17:28
  • for that u need to make sure that all other elements are hidden except `i`. So in the event listener, loop over all the content elements and hide all of them and then make the `i`th element visible. Hope it helps @RayElshobokshy – uditkumar01 Jan 01 '23 at 17:30
  • yes now it all works fine! thank you! – Ray Elshobokshy Jan 01 '23 at 17:37
  • Declaring `i` with `let` instead of `var` would also keep `i`'s value distinct in each iteration. See [this explanation](https://stackoverflow.com/a/35812376/13561410). – Oskar Grosser Jan 01 '23 at 18:57