Haizz. Hello guys..
I'm learning Web Dev in: https://www.w3schools.com/.
I did a very simple homework here: https://www.w3schools.com/howto/tryit.asp?filename=tryhow_js_tabs
```
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
body {font-family: Arial;}
/* Style the tab */
.tab {
overflow: hidden;
border: 1px solid #ccc;
background-color: #f1f1f1;
}
/* Style the buttons inside the tab */
.tab button {
background-color: inherit;
float: left;
border: none;
outline: none;
cursor: pointer;
padding: 14px 16px;
transition: 0.3s;
font-size: 17px;
}
/* Change background color of buttons on hover */
.tab button:hover {
background-color: #ddd;
}
/* Create an active/current tablink class */
.tab button.active {
background-color: #ccc;
}
/* Style the tab content */
.tabcontent {
display: none;
padding: 6px 12px;
border: 1px solid #ccc;
border-top: none;
}
</style>
</head>
<body>
<h2>Tabs</h2>
<p>Click on the buttons inside the tabbed menu:</p>
<div class="tab">
<button class="tablinks" onclick="openCity(event, 'London')">London</button>
<button class="tablinks" onclick="openCity(event, 'Paris')">Paris</button>
<button class="tablinks" onclick="openCity(event, 'Tokyo')">Tokyo</button>
</div>
<div id="London" class="tabcontent">
<h3>London</h3>
<p>London is the capital city of England.</p>
</div>
<div id="Paris" class="tabcontent">
<h3>Paris</h3>
<p>Paris is the capital of France.</p>
</div>
<div id="Tokyo" class="tabcontent">
<h3>Tokyo</h3>
<p>Tokyo is the capital of Japan.</p>
</div>
<script>
function openCity(evt, cityName) {
var i, tabcontent, tablinks;
tabcontent = document.getElementsByClassName("tabcontent");
for (i = 0; i < tabcontent.length; i++) {
tabcontent[i].style.display = "none";
}
tablinks = document.getElementsByClassName("tablinks");
for (i = 0; i < tablinks.length; i++) {
tablinks[i].className = tablinks[i].className.replace(" active", "");
}
document.getElementById(cityName).style.display = "block";
evt.currentTarget.className += " active";
}
</script>
</body>
</html>
```
But.... When I try to exchange the traditional for-loop to for..in loop. It not work?
Ex.
for (i in tabcontent) {
tabcontent[i].style.display = "none";
}
After many time I try to make it work. I've found that all statement follow the first for..in loop will be skip !!!???? It mean the Function will auto-break after a for..in loop. The first for..in loop work as normal, but the rest statement after it is simply skip. The Function break at this point?
If anyone knew this problem please help me to understand it. X__X
The purpose the break statement is to break out of a loop early. For example if the following code asks a use input a integer number x. If x is divisible by 5, the break statement is executed and this causes the exit from the loop.
The “for” loop Executes once upon entering the loop. Checked before every loop iteration. If false, the loop stops. Runs again and again while the condition is truthy.
You'll put the break statement within the block of code under your loop statement, usually after a conditional if statement.
A break statement, when used inside the loop, will terminate the loop and exit. If used inside nested loops, it will break out from the current loop. A continue statement will stop the current execution when used inside a loop, and the control will go back to the start of the loop.
The "auto-break" you're seeing is an uncaught exception breaking execution – you should have your browser's console open to see any errors that occur and are uncaught.
That change yields an
Uncaught TypeError: Cannot set property 'display' of undefined
at openCity (<anonymous>:6:33)
at HTMLButtonElement.onclick (tryit.asp?filename=tryhow_js_tabs:1)
since for..in
loops over properties of objects, not array elements as you imagine, and i
ends up (as evidenced by console.log(i)
) being 0
, 1
, 2
, and then finally length
, and tabcontent.length
has no style
property, so the equivalent of
tabcontent.length.style.display = ...
naturally fails.
You can go with the for in loop. The loop will give you indexes but because you have not converted it to an array you get some extra (unwanted properties) hence the error.
The key is to make the conversion, after that you are safe with the for in loop:let tabContent = Array.from(document.getElementsByClassName("tabcontent"))
Example proof: https://jsfiddle.net/sqfgb0k6/
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
body {
font-family: Arial;
}
/* Style the tab */
.tab {
overflow: hidden;
border: 1px solid #ccc;
background-color: #f1f1f1;
}
/* Style the buttons inside the tab */
.tab button {
background-color: inherit;
float: left;
border: none;
outline: none;
cursor: pointer;
padding: 14px 16px;
transition: 0.3s;
font-size: 17px;
}
/* Change background color of buttons on hover */
.tab button:hover {
background-color: #ddd;
}
/* Create an active/current tablink class */
.tab button.active {
background-color: #ccc;
}
/* Style the tab content */
.tabcontent {
display: none;
padding: 6px 12px;
border: 1px solid #ccc;
border-top: none;
}
</style>
</head>
<body>
<h2>Tabs</h2>
<p>Click on the buttons inside the tabbed menu:</p>
<div class="tab">
<button class="tablinks" onclick="openCity(event, 'London')">London</button>
<button class="tablinks" onclick="openCity(event, 'Paris')">Paris</button>
<button class="tablinks" onclick="openCity(event, 'Tokyo')">Tokyo</button>
</div>
<div id="London" class="tabcontent">
<h3>London</h3>
<p>London is the capital city of England.</p>
</div>
<div id="Paris" class="tabcontent">
<h3>Paris</h3>
<p>Paris is the capital of France.</p>
</div>
<div id="Tokyo" class="tabcontent">
<h3>Tokyo</h3>
<p>Tokyo is the capital of Japan.</p>
</div>
<script>
function openCity(evt, cityName) {
let i, tablinks
let tabContent = Array.from(document.getElementsByClassName("tabcontent"))
for (let i in tabContent) {
tabContent[i].style.display = "none";
}
tablinks = document.getElementsByClassName("tablinks");
for (let i in tabContent) {
tablinks[i].className = tablinks[i].className.replace(" active", "");
}
document.getElementById(cityName).style.display = "block";
evt.currentTarget.className += " active";
}
</script>
</body>
</html>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With