Starr Oge
Starr Oge

Reputation: 23

How to Continue to Change Element with While Loop

I've been trying to get display a bunch of letters that continuously change. They only change each time I reload the page. Please help.

    const action = false;
    var i = 0; 
    
    function randomized() {
      var text = "";
      var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
      const still = document.getElementById('c1');
      const still2 = [document.getElementById('c1'),document.getElementById('c2'),document.getElementById('c3'),document.getElementById('c4'),document.getElementById('c5'),document.getElementById('c6'),document.getElementById('c7'),document.getElementById('c8'),document.getElementById('c9'),document.getElementById('c10'),document.getElementById('c11'),document.getElementById('c12')]
    
    while (action === false) {
    	i++;
    	var letter = possible.charAt(Math.floor(Math.random() * possible.length));
    	still2[i].innerHTML = letter;
    }
      /*for(var i = 0; action === false; i++){
      	var letter = possible.charAt(Math.floor(Math.random() * possible.length))
        still2[i].innerHTML = letter;
    	};*/
    }

Upvotes: 0

Views: 59

Answers (3)

Pablo
Pablo

Reputation: 6058

As mentioned in another answer the while loop will lock the main thread and it will never render anything. I suggest using the requestAnimationFrame() function to queue the updates for the elements.

Below is a proof of concept you can adapt to your specific case:

  • A function to generate the random character
  • User global <span> selector for simplicity
  • A function to loop through the elements, update their content and queue the next frame indefinitely.
  • For the demo purposes stop the loop after 2 seconds. Note how the last frame animation is logged and used to then stop the infinite loop.

// Generate random letter
function randomLetter() {
  const possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  return possible.charAt(Math.floor(Math.random() * possible.length));
}

// Id to stop the animation frame loop
let animationId = 0;

// Update all nodes at the same time
function updateNodes() {
  // List all nodes to update
  let nodes = document.getElementsByTagName('span');

  for (let i = 0; i < nodes.length; i++) {
    nodes[i].innerHTML = randomLetter();
  }

  // Queue the next update
  animationId = requestAnimationFrame(updateNodes);
}

// Start the animation loop
animationId = requestAnimationFrame(updateNodes);

// Stops animation after 2 seconds
setTimeout(function(){
  cancelAnimationFrame(animationId);
}, 2000);
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>

Upvotes: 1

stealththeninja
stealththeninja

Reputation: 3791

The while loop locks the thread and prevents the page from rendering each of your letters. Try setInterval() or similar asynchronous loop to release the thread and show each new letter:

function setRandomLetter() {
  const possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  const still = document.getElementById('c1');
  const letter = possible.charAt(Math.floor(Math.random() * possible.length));

  still.innerText = letter;
}

// set a random letter every second
setInterval(setRandomLetter, 1000);
<span id="c1"></span>

Upvotes: 0

Dhana
Dhana

Reputation: 1658

Call your page load method inside window.onload and use localStorage

 window.onload = function() { 
        randomized(localStorage.getItem("randomString"));// Retrieve
 }

function randomized(preRandomString){
    // Store and update localStorage
    return prvRandomString + localStorage.setItem("randomString", "abc123");
}

Upvotes: 0

Related Questions