1

I am trying to generate a simple webpage will generate a random value. Right now I am able to select a button and it will select a value out of my list, but I wanted to try to make the webpage look like it was cycling through the items in the list until it stops. The code below will have the values change in the console display but it will only the webpage with the last value selected randomly instead of updating the webpage each time a new value is selected. In the code below I was able to get random change with the Random1 button. Random2 will generate a different item in the list 10 times (once per second) but the webpage doesn’t update until the 10th update.

HTML Code:

<html>
<body>
<div>
    <p>Round and Round we go.  Where it will stop no one will know.  Time to play the game.</p>
    <p id="one">What is going to be?</p>
    <button onclick="random()">Random1</button>
    <button onclick="main()">Random2</button>
    <button onclick="main1()">Random3</button>
</div>
</body>
<html>

JavaScript Code: I have the follow code inserted into the HTML code above

<script>
    var timeNow, startTime, endTime, secondsCnt, secondsDiff ;

    <!--Define the start time as the time that the script was started-->
    function start() {
        startTime = new Date();
    }
    <!--Define the end time as the time that the randomizer should complete-->
    function end() {
        var duration = 10;
        endTime = new Date(startTime.getTime() + duration*1000);
    }
    <!--Calculate the time in seconds remaining for execution-->
    function timeRemaining() {
        var timeDiff = startTime - timeNow;
        var timeElapse = endTime - timeNow;
    
        timeDiff /= 1000;
        timeElapse /= 1000;
    
        secondsDiff = Math.round(timeDiff * -1);
        secondsCnt = Math.round(timeElapse);
    }
    <!--Sleep function to pause the script for a value (in ms)-->
    function sleep(millisecondsCnt) {
        const date = Date.now();
        let currentDate = null;
        do {
            currentDate = Date.now();
        } while (currentDate - date < millisecondsCnt);
    }
    <!--Randomizer function that will select a value from a list and then update the HTML for the id-->
     function random(){
         var people = [
                    "A",
                    "B",
                    "C",
                    "D",
                    "E",
                    "F",
                    "G",
                    "H",
                    "I",
                    "J",
                    "K",
                    "L",
                    "M",
                    "N",
                    "O",
                    "P"
        ];

        <!--Define a random value and update the inner HTML (or text) for the Id "one" -->
        var ranVal = people[Math.floor(Math.random() * people.length)];
        document.getElementById("one").innerHTML = ranVal;
    
        return ranVal;
    }
    <!--Main function to call the subroutines that need to executed to select a random value-->
    function main() {
        <!-- Define the times-->
        var sleepTime = 0;
        start();
        end();
        timeNow = new Date();
    
        <!--Loop until time now reaches the endTime to terminate-->
        while (timeNow <= endTime) {
            <!--Calculate the time remaining in for the script to execute
            timeRemaining();
        
            <!--Wait for 1 second before continuing to execute-->
            sleep(1000);
        
            <!--Call the function that will calculate the random value-->
            var newVal = random();
            console.log(document.getElementById("one").innerHTML);

            <!--I tried to write to the tag during the main instead of the random function, but I got the same results-->
            <!--document.getElementById("one").innerHTML = newVal;-->

            <!--Reset the time now variable-->
            timeNow = new Date();
        }
    }
</script>

Below is a second function that I was trying for the Random3 button, but I get the same result. For the third method, I was trying to use the setInterval and clearInterval commands.

<!--Different attempt to achieve the goal of changing the value to multiple random values. -->
function main1() {
    var sleepTime = 0;
    start();
    end();
    timeNow = new Date
    var myInterval = setInterval(random(),1000);
    while (timeNow <= endTime) {
        timeRemaining();
        sleepTime = (1 * Math.pow(Math.E,(0.7*secondsDiff)));
        <!--Just used this to slow down the output for now-->
           sleep(1000);
        
        var newVal = random();
        console.log(document.getElementById("one").innerHTML);
        <!--document.getElementById("one").innerHTML = newVal;-->
        
        timeNow = new Date();
    }
    clearInterval(myInterval);
}

Right now I just want to be able to cycle through the items in the list for 10 seconds (changing once a second) but later I was planning on making it look kind of like it was cycling through values as if it was spinning on a wheel. The code seems to be performing the intended functionality, but the web page is not updating in the same way that the value is.

OAR617
  • 79
  • 9

1 Answers1

0

The reason is that because you are using a while loop that pauses the javascript, everything is paused, the browser cannot render the web page, the buttons can't be clicked, and the entire website basically is stopped. The reason it only changes until it's finished is that it is just constantly running the while loop, and the browser can only have time to render until it's done running. Using a while loop isn't a great way to do this, and I would recommend using setTimeout like this:

setTimeout(()=>{
    //code here
},1000) // 1000 is in milliseconds

With set time out, it is asynchronous and will not block everything else that is happening and slow down everything.

Another thing is set interval, which repeats the code every certain amount of time.

So this is all you need for your code:

var counter = 0
function random(){
     var people = [
                "A",
                "B",
                "C",
                "D",
                "E",
                "F",
                "G",
                "H",
                "I",
                "J",
                "K",
                "L",
                "M",
                "N",
                "O",
                "P"
    ];

    var ranVal = people[Math.floor(Math.random() * people.length)];
    document.getElementById("one").innerHTML = ranVal;

    return ranVal;
}
function main() {
    if(counter < 10){ // check if it has looped 10 ten times already
         setTimeout(()=>{
            var newVal = random();
            console.log(document.getElementById("one").innerHTML);
            counter ++ 

            main() //calls the function again
        },1000)
    }else{
        counter = 0 //if it has looped 10 times reset the counter and stop
    }
}
<html>
<body>
<div>
    <p>Round and Round we go.  Where it will stop no one will know.  Time to play the game.</p>
    <p id="one">What is going to be?</p>
    <button onclick="random()">Random1</button>
    <button onclick="main()">Random2</button>
    <button onclick="main1()">Random3</button>
</div>
</body>
<html>
Tony Zhang
  • 417
  • 4
  • 8
  • That accomplish my goal, but I have a follow up question. To get the code to run I had to change the syntax "setTimeout(()=>{Insert Code}" to "setTimeout(function() {Insert Code}" and then it ran without error. What would cause this syntax to work sometimes? – OAR617 May 03 '21 at 02:37