slumbergeist
slumbergeist

Reputation: 1538

pause and resume setInterval in javascript

I am trying to mimic the typing effect on the codility's home page in JavaScript.I have already achieved the typing and deleting effect using setInterval().

Here's the jsfiddle of that: https://jsfiddle.net/yzfb8zow/

var span=document.getElementById("content");
var strings=["hello world","how r u??"];

var index=0;    //get string in the strings array
var chIndex=0;  //get char in string
var type=true;

setInterval(function(){
  if(index===strings.length)
    index=0;
  if(type){
    typeIt();
  }
  else
    deleteIt();
},200);

// type the string
function typeIt(){
  if(chIndex<strings[index].length)
    span.innerHTML=strings[index].substring(0,chIndex++);
  else
    type=false;
}

//delete the string
function deleteIt(){
  if(chIndex===0){
    index++;
    type=true;
  }
  else
    span.innerHTML=strings[index].substring(0,chIndex--);
}

the html

<span id="content"></span>
<span id="cursor">|</span>

the css

#cursor{
  -webkit-animation: 1s blink step-end infinite;
  -moz-animation: 1s blink step-end infinite;
  animation: 1s blink step-end infinite;
}

@keyframes blink {
  from, to {
    opacity:0;
  }
  50% {
    opacity: 1;
  }
}

@-moz-keyframes blink {
  from, to {
    opacity:0;
  }
  50% {
    opacity:1;
  }
}

@-webkit-keyframes blink {
  from, to {
    opacity:0;
  }
  50% {
    opacity:1;
  }
}

What I can't get my head around is how could I pause the setInterval function at the beginning of string change and at the end to get a clear blinking cursor.

I have looked up other answers Pause and resume setInterval and How do I stop a window.setInterval in javascript? but I am unable to comprehend how to use it in this context.

Also it would be great if you could tell me how to improve my code.

Upvotes: 3

Views: 2684

Answers (2)

atrifan
atrifan

Reputation: 172

I edited your code here is your jsfiddle back: https://jsfiddle.net/yzfb8zow/5/

Also a little code explanation

var typingFunction = function() {
  if (index === strings.length) {
    index = 0;
  }

  if (type) {
    typeIt();
  } else {
    deleteIt();
  }
}

I declared your previous typing function to later be able to use it as desired.

var x = setInterval(typingFunction.bind(typingFunction), 200);

Stored the interval so I can clear it later - stored in a global variable (not necessarily ok and there are other solutions but store it).

function typeIt() {
 if (chIndex == -1) {
    chIndex += 1;
    clearAndRestartInterval(1000);
    return;
  }


  if (chIndex <= strings[index].length) {
    span.innerHTML = strings[index].substring(0, chIndex++);
  } else {
    clearAndRestartInterval(1000);
    type = false;
    return;
  }
}

In the typeIt function I clear interval at the begining at chIndex = -1, wait a while so letting the cursor blink before I restart the interval. Than I clear it again at the end of the string. My chIndex starts from -1 so I know when to blink at the begining.

Rest of the code is self explanatory.

Feel free to edit the parameter of the clearAndRestartInterval function in order to set the time of the blinking at the begining and the end.

function clearAndRestartInterval(timeOfRestart) {
    clearInterval(x);
    setTimeout(function() {
      x = setInterval(typingFunction.bind(typingFunction), 200);
    }, timeOfRestart);
}

Last but not least the stop and restart function of the interval. This is quite simple and x - is the previously declared setInterval - globally which I clear and reset with a new interval ofter some time.

Hope this helps.

Cheers

Upvotes: 3

Rajesh
Rajesh

Reputation: 24925

You will have to use nested timeouts.

  • Call typeIt directly, as its a default action.
  • In typeIt, add a setTimeout which will call deleteIt on completion.
  • On completion of deleteIt, call typeIt again.

Sample Fiddle

You typeit will look something like this:

function typeIt() {
  var t_interval = setInterval(function() {
    if (chIndex <= strings[index].length)
      span.innerHTML = strings[index].substring(0, chIndex++);
    else {
      type = false;
      // This is to be executed once action is completed.
      window.clearInterval(t_interval);
    }
  }, 20)
}

Upvotes: 2

Related Questions