2

I'm making a simple HTML/CSS/JavaScript text demo on codePen and I'm having issues with looping a function in the JavaScript. Here's what I have so far.

function loop() {
    var i;
    for (i = 0; i < 4; i++) {
        flicker();
    }
    var wait = (Math.random() * 4000);
    setTimeout(loop, wait);
}

function flicker() {
    $("#text").toggleClass('on');
}

loop();

If I take out the for loop, the text flickers. As soon as I add it back in, it freezes. Any help would be appreciated.

EDIT: The effect I'm trying to get is 2 to 4 quick flickers, a longer pause, and then another set of flickers. Think neon signs. The codepen link is here if it helps.

2

2 Answers 2

3

That's because you are looping the "setTimeout" while "setTimeout" is still active. You sum up the timeouts which leads to an error.

What you are searching for is not a "for loop". Check this code (thanks Kaiido):

var lastTime = 0;

function flickerPauses(){
  if(lastTime < 5){
    lastTime ++;
    return Math.random()*100;
  }else{
    lastTime = 0;
    return Math.random()*1200 + 100;
  }
}

function flicker() {
  $("#text").toggleClass('on');
  setTimeout(flicker, flickerPauses());
}

flicker();
.on{
  display: none;
}
div{
  color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="text"> Beer </div>

An early version which works but isn't as good as the first snippet:

var inter;

function setInter(){
  inter = setInterval(flicker, Math.random() * 100);
}

function flicker() {
    $("#text").toggleClass('on');
    clearInterval(inter);
    setInter();
}

setInter();
.on{
  display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="text"> asdf </div>

Sign up to request clarification or add additional context in comments.

10 Comments

But this will not have a random timeout between calls. It will "pulse" and not "flicker".
@JoeFrambach Sorry, I'll adapt this
@Kaiido Joe already pointed this out. I've adapted my code. I hope you love it this time ;)
That's better :-) But doesn't fit the new requirement in OP's question (I hate when they do that…)
@Kaiido :D :'( I'll adapt it <.<
|
2

If you simply change 4 to 3, it will work fine. Or any odd number really. I recommend 1, and remove the loop.

Why?

Initial state -> off.
1 -> on.
2 -> off.
3 -> on.
4 -> off.

Every 1-4000 ms, you are doing absolutely nothing by keeping the state back to its starting place.


Edit: I now see what you are trying to accomplish. Here is an updated jsfiddle: http://jsfiddle.net/L2nt33os/6/

It should do what you need.

$(function () {
    function longFlicker(callback) {
        $("#text").toggleClass('on');
        var wait = 1000+(Math.random() * 3000);
        setTimeout(shortFlickers, wait, 5);
    }
    function shortFlickers(remaining) {
        if (!remaining) return longFlicker();
        $("#text").toggleClass('on');
        var wait = (Math.random() * 300);
        setTimeout(shortFlickers, wait, remaining-1);
    }
    longFlicker();
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.