I created a tabbed panel with Javascript. When I am doing it without any programming it is working fine but after putting some it with some conditional and looping statements it is not working. Some problem is coming while making a programme in javascript. Kindly click below to look entire coding in jsfiddle and suggest me how to fix the error. Thanks
HTML :
<button class="tabButton">Tab 01</button>
<button class="tabButton">Tab 02</button>
<button class="tabButton">Tab 03</button>
<button class="tabButton">Tab 04</button>
<button class="tabButton">Tab 05</button>
<div class="tabPanel" style="display:block">
<h3>Tab panel 01</h3>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed in rebus apertissimis nimium longi sumus. Quicquid porro animo cernimus, id omne oritur a sensibus; Ergo instituto veterum, quo etiam Stoici utuntur, hinc capiamus exordium. Philosophi autem in suis lectulis plerumque moriuntur. Falli igitur possumus.
</p>
</div>
<div class="tabPanel">
<h3>Tab panel 02</h3>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed in rebus apertissimis nimium longi sumus. Quicquid porro animo cernimus, id omne oritur a sensibus; Ergo instituto veterum, quo etiam Stoici utuntur, hinc capiamus exordium. Philosophi autem in suis lectulis plerumque moriuntur. Falli igitur possumus.
</p>
</div>
<div class="tabPanel">
<h3>Tab panel 03</h3>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed in rebus apertissimis nimium longi sumus. Quicquid porro animo cernimus, id omne oritur a sensibus; Ergo instituto veterum, quo etiam Stoici utuntur, hinc capiamus exordium. Philosophi autem in suis lectulis plerumque moriuntur. Falli igitur possumus.
</p>
</div>
<div class="tabPanel">
<h3>Tab panel 04</h3>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed in rebus apertissimis nimium longi sumus. Quicquid porro animo cernimus, id omne oritur a sensibus; Ergo instituto veterum, quo etiam Stoici utuntur, hinc capiamus exordium. Philosophi autem in suis lectulis plerumque moriuntur. Falli igitur possumus.
</p>
</div>
<div class="tabPanel">
<h3>Tab panel 05</h3>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed in rebus apertissimis nimium longi sumus. Quicquid porro animo cernimus, id omne oritur a sensibus; Ergo instituto veterum, quo etiam Stoici utuntur, hinc capiamus exordium. Philosophi autem in suis lectulis plerumque moriuntur. Falli igitur possumus.
</p>
</div>
css:
.tabPanel{
width:500px;
height:150px;
background-color:grey;
margin:0;
padding:20px;
display:none;
}
Javascript:
for (i=0; i<tabBtn.length; i++) {
tabBtn[i].onclick = function(){
for(r=0; r<panel.length; r++){
if ( i==r ){
panel[r].style.display = "block";
} else {
panel[r].style.display = "none";
}
}
}
}
What is happening here is that by the time the 'onclick' handler runs, the for loop has already completed.
Think of it like this: Javascript encounters the for loop, loops through 5 times, attaches the handlers then exits the for loop.
When tabBtn is clicked on, it has the final value of the for loop stored inside. i
will ALWAYS be equal to 5. Try it yourself, console.log(i)
within your click handler and you will see it's always 5.
How do we fix this? Well, we take advantage of something called a closure. A closure is a function that will 'save' the value of i and pass it to your click handler. There is plenty of documentation on closures, and while it is a more advanced JS topic I would recommend reading up on it.
Anyway, here is how you would use a closure to fix it:
for (i = 0; i < tabBtn.length; i++) {
//Here is our 'closure' an Immediately Invoked anonymous function whose job is to pass (i)!
(function(i) {
tabBtn[i].onclick = function() {
for (r = 0; r < panel.length; r++) {
if (i == r) {
panel[r].style.display = "block";
} else {
panel[r].style.display = "none";
}
}
}
//Here we pass it (i) at the run time.
})(i);
}
Check an updated demo here: https://jsfiddle.net/vwc42r9x/21/