Search code examples
javascripthtmlsyntax-error

setinterval doesn't stop in my js code but it should run


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 class="been">google</p>
            <p class="been">google</p>
            <p class="been">google</p>
            <p class="been">google</p>
            <p class="been">google</p>
            <p class="been">google</p>
            <p class="been">google</p>
            <p class="been">google</p>
            <p class="been">google</p>
            <p class="been">google</p>
            <p class="been">google</p>
            <p class="been">google</p>
            <p class="been">google</p>
            <p class="been">google</p>
            <p class="more" 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


Solution

  • 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 class="been">google</p>
                <p class="been">google</p>
                <p class="been">google</p>
                <p class="been">google</p>
                <p class="been">google</p>
                <p class="been">google</p>
                <p class="been">google</p>
                <p class="been">google</p>
                <p class="been">google</p>
                <p class="been">google</p>
                <p class="been">google</p>
                <p class="been">google</p>
                <p class="been">google</p>
                <p class="been">google</p>
                <p class="more" onclick="more_list();">view more...</p>
            </div>
        </div>
    </body>