setinterval doesn't stop in my js code even though my conditional statement becomes false when it reaches 14 and else should be executed
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>live site</title>
<link rel="stylesheet" href="style.css">
<style>
@keyframes color {
0% {
background: #33CCCC;
}
20% {
background: #33CC36;
}
40% {
background: #B8CC33;
}
60% {
background: #FCCA00;
}
80% {
background: #33CC36;
}
100% {
background: #33CCCC;
}
}
body {
background: #000000;
}
#list-var {
background-color: #272727;
max-width: 400px;
padding: 5px 10px;
}
p {
background-color: #161616;
border-radius: 2px;
margin: 5px 0;
text-align: center;
color: #005e5e;
padding: 5px 0;
font-family: fantasy;
}
.been {
display: none;
}
.more {
background-color: #000000;
cursor: pointer;
animation: color 9s infinite linear;
}
</style>
</head>
<body>
<div id="boxing">
<div id="list-var">
<p>google</p>
<p>google</p>
<p>google</p>
<p>google</p>
<p>google</p>
<p >google</p>
<p >google</p>
<p >google</p>
<p >google</p>
<p >google</p>
<p >google</p>
<p >google</p>
<p >google</p>
<p >google</p>
<p >google</p>
<p >google</p>
<p >google</p>
<p >google</p>
<p >google</p>
<p onclick="more_list();">view more...</p>
</div>
</div>
</body>
<script>
function more_list() {
var been_tag = document.getElementsByClassName('been');
var for_speed = setInterval(sett, 200);
var i = 0;
function sett() {
console.log(i);
been_tag[i].style.display = "block";
if (been_tag.length >= i) {
i ;
} else {
clearInterval(for_speed);
}
}
}
</script>
</html>
and error:
index.html:106 Uncaught TypeError: Cannot read properties of undefined (reading 'style') at sett (index.html:106:25)
I know that I have a bug, but I tried a lot, but I haven't found that bug
CodePudding user response:
The issue is
if (been_tag.length >= i) {
i ;
}
Imagine been_tag
is empty.
if (0 >= 0) // true
then you will still do the next iteration,
been_tag[0].style.display = "block";
even though been_tag
has nothing in it. You need to instead do:
if (been_tag.length - 1 >= i) {
been_tag[i].style.display = "block";
i
}
so that you only do the access of the element at i
if it actually exists:
function more_list() {
var been_tag = document.getElementsByClassName('been');
var for_speed = setInterval(sett, 200);
var i = 0;
function sett() {
if (been_tag.length - 1 >= i) {
been_tag[i].style.display = "block";
i
} else {
clearInterval(for_speed);
}
}
}
@keyframes color {
0% {
background: #33CCCC;
}
20% {
background: #33CC36;
}
40% {
background: #B8CC33;
}
60% {
background: #FCCA00;
}
80% {
background: #33CC36;
}
100% {
background: #33CCCC;
}
}
body {
background: #000000;
}
#list-var {
background-color: #272727;
max-width: 400px;
padding: 5px 10px;
}
p {
background-color: #161616;
border-radius: 2px;
margin: 5px 0;
text-align: center;
color: #005e5e;
padding: 5px 0;
font-family: fantasy;
}
.been {
display: none;
}
.more {
background-color: #000000;
cursor: pointer;
animation: color 9s infinite linear;
}
<body>
<div id="boxing">
<div id="list-var">
<p>google</p>
<p>google</p>
<p>google</p>
<p>google</p>
<p>google</p>
<p >google</p>
<p >google</p>
<p >google</p>
<p >google</p>
<p >google</p>
<p >google</p>
<p >google</p>
<p >google</p>
<p >google</p>
<p >google</p>
<p >google</p>
<p >google</p>
<p >google</p>
<p >google</p>
<p onclick="more_list();">view more...</p>
</div>
</div>
</body>