JBoy
JBoy

Reputation: 5735

Display text in time intervals with CSS and JS

I would like to create, using the setInterval() JS function, a visual effect that displays text one character at the time with an interval of 100ms per character, on an Angular application.

Note that this happens in the index.html within the <app-root> tags, so it will appear only while the app is bootstrapped. After reading the setInterval() page i thought that this would make the job, so this is my code:

var divs=['rBox','aBox','tBox','sBox'];
var index=-1;

function displayChars(){
  for(container of divs){
    document.getElementById(container).style.visibility='hidden';  
  }
  var fun = setInterval(display,100);
}

function display(){
  if(index < 4){
    document.getElementById(divs[++index]).style.visibility='visible'
  }else{
    clearInterval(fun);
  }
}
displayChars();
<app-root>
  <div class="rats-div">
    <div id="rBox">1</div>
    <div id="aBox">2</div>
    <div id="tBox">3</div>
    <div id="sBox">4..</div>
  </div>
</app-root>

But it does not display anything, the divs containing the numbers are there with visibility set to hidden but it seems like they are never set to visible

I can't see where the problem lies. If I look at the code from an algorithmic point of view, I guess I probably don't understand very well the inner working of setInterval().

Upvotes: 0

Views: 1436

Answers (5)

VXp
VXp

Reputation: 12068

Pure CSS solution, if an option, looks something like this:

.rats-div > div {
  opacity: 0; /* or "visibility: hidden" */
  animation: opacity .1s forwards;
}

.rats-div > div:nth-child(2) {animation-delay: .1s}
.rats-div > div:nth-child(3) {animation-delay: .2s}
.rats-div > div:nth-child(4) {animation-delay: .3s}

@keyframes opacity {
  to {opacity: 1} /* or "visibility: visible / initial" */
}
<div class="rats-div">
  <div id="rBox">1</div>
  <div id="aBox">2</div>
  <div id="tBox">3</div>
  <div id="sBox">4..</div>
</div>

Upvotes: 1

CodeF0x
CodeF0x

Reputation: 2682

  • Your variable fun needs to be global, otherwise display() can't access it
  • Don't forget to declare container in your for...of loop as an actual variable
  • You where incrementing index too often

var divs = ['rBox', 'aBox', 'tBox', 'sBox'];
var index = -1;
var fun;

function displayChars() {
  for (var container of divs) {
    document.getElementById(container).style.visibility = 'hidden';
  }
  fun = setInterval(display, 100);
}

function display() {
  if (index < 3) {
    document.getElementById(divs[++index]).style.visibility = 'visible';
  } else {
    clearInterval(fun);
  }
}
displayChars();
<app-root>
  <div class="rats-div">
    <div id="rBox">1</div>
    <div id="aBox">2</div>
    <div id="tBox">3</div>
    <div id="sBox">4..</div>
  </div>
</app-root>

Upvotes: 1

Peter B
Peter B

Reputation: 24147

After minor modifications it's working, see below. I changed index to start at 0 and to be used with divs[index++] (so use-then-increment), and to compare it with divs.length instead of hardcoded 4. Also I put variable fun at the global level.

var divs = ['rBox', 'aBox', 'tBox', 'sBox'];
var index = 0;
var fun = -1; // timer handle

function displayChars() {
  for (container of divs) {
    document.getElementById(container).style.visibility = 'hidden';
  }
  fun = setInterval(display, 100);
}

function display() {
  if (index < divs.length) {
    document.getElementById(divs[index++]).style.visibility = 'visible'
  } else {
    clearInterval(fun);
  }
}

displayChars();
<div class="rats-div">
  <div id="rBox">1</div>
  <div id="aBox">2</div>
  <div id="tBox">3</div>
  <div id="sBox">4..</div>
</div>

Upvotes: 2

Inus Saha
Inus Saha

Reputation: 1918

var divs=['rBox','aBox','tBox','sBox'];
var index=0;
var fun=null;
function displayChars(){
  for(container of divs){
    document.getElementById(container).style.visibility='hidden';
  }
  fun = setInterval(display,100);
}

function display(){
  if(index < 4){
    document.getElementById(divs[index]).style.visibility='visible'
    index++;
  }else{
    clearInterval(fun);
  }
}

displayChars();
<app-root>
        <div class="rats-div">
          <div id="rBox">1</div>
          <div id="aBox">2</div>
          <div id="tBox">3</div>
          <div id="sBox">4..</div>
        </div>
    </app-root>

try this code. it should do your job.

Upvotes: 0

Adelin
Adelin

Reputation: 8209

fun was not declared globally

And index was incremented too much

A rough update to the code:

var divs=['rBox','aBox','tBox','sBox'];
var index=-1;
var fun
function displayChars(){
  for(container of divs){
    document.getElementById(container).style.visibility='hidden';  
  }
  fun = setInterval(display,100);
}

function display(){
  if(index < 3){
    document.getElementById(divs[++index]).style.visibility='visible'
  }else{
    clearInterval(fun);
  }
}
displayChars()
<app-root>
  <div class="rats-div">
    <div id="rBox">1</div>
    <div id="aBox">2</div>
    <div id="tBox">3</div>
    <div id="sBox">4..</div>
  </div>
</app-root>

Upvotes: 3

Related Questions