0

I have a setInterval function that changes an elements innerHTML from an array, every half a second. I would like to show the fifth item for 5 seconds, but then resume the setInterval at every half a second.

I tried changing the speed during the setInterval:

if (wordsCnt==5) {
     speed = 5000
  }else{
    speed = 500
  }

var speed = 500

var cycleWords = document.getElementById("cycle-words");
var wordsCnt = 0;
var words = [
  "Graphic designers", 
  "Founders",
  "Photographers",
  "Copywriters",
  "Audio designers",
  "Startups",
  "Film makers",
  "Architects",
  "Instagramers"
];


window.setInterval(function() {
  cycleWords.innerHTML = words[wordsCnt];
  if (wordsCnt < words.length-1) {
    wordsCnt++;
  } else {
    wordsCnt = 0;
  }
  
 if (wordsCnt==5) {
     speed = 5000
  }else{
    speed = 500
  }
}, speed);
<div id="">
 Working with <span id="cycle-words">Copy writers</span></div>
</div>

The speed remains the same.

user1059511
  • 257
  • 1
  • 4
  • 18
  • function loop() { ...; setTimeout(loop, speed); } –  Jul 12 '19 at 08:35
  • Possible duplicate of [Changing the interval of SetInterval while it's running](https://stackoverflow.com/questions/1280263/changing-the-interval-of-setinterval-while-its-running) – showdev Jul 12 '19 at 08:36
  • you could take a lazy approach and add so much same items until you got the wanted lengt of displaying the same word ... – Nina Scholz Jul 12 '19 at 08:38

5 Answers5

1

A setInterval will continue running with the values passed as arguments, there is no way to change that. You could cancel the interval and create a new one, but in that case it just makes sense to start a new timeout with setTimeout whenever the previous finished.

// No need for speed ...

// Consider using let & const over var, as they are more steict and you can find errors more easily

const cycleWords = document.getElementById("cycle-words");
let wordsCnt = 0;
const words = ["Graphic designers", "Founders", "Photographers", "Copywriters", "Audio designers", "Startups", "Film makers", "Architects", "Instagramers"];

setTimeout(function showWord() { // name the function, so that we can refer to it later
  cycleWords.innerHTML = words[wordsCnt];
  wordsCnt = (wordsCnt + 1) % words.length; // the modulo operator makes that task easier
  if (wordsCnt === 5) { // use === instead of ==, that saves you from headaches!
    setTimeout(showWord, 5000); // create a new timer
  } else {
    setTimeout(showWord, 500);
  }
}, 500);
<div>Working with <span id="cycle-words">Copy writers</span></div>
mplungjan
  • 169,008
  • 28
  • 173
  • 236
Jonas Wilms
  • 132,000
  • 20
  • 149
  • 151
0

You can use setTimeout instead of the set time interval. Here the code you can use

function setDeceleratingTimeout(callback, factor, times)
{
    var internalCallback = function(tick, counter) {
        return function() {
            if (--tick >= 0) {
                window.setTimeout(internalCallback, ++counter * factor);
                callback();
            }
        }
    }(times, 0);

    window.setTimeout(internalCallback, factor);
};

// console.log() requires firebug    
setDeceleratingTimeout(function(){ console.log('hi'); }, 10, 10);
setDeceleratingTimeout(function(){ console.log('bye'); }, 100, 10);
Rahul Rana
  • 455
  • 2
  • 7
0

You could change the word count for index 4 and add per cycle only 0.1 instead of one.

var speed = 500,
    cycleWords = document.getElementById("cycle-words"),
    wordsCnt = 0,
    words = ["Graphic designers", "Founders", "Photographers", "Copywriters", "Audio designers", "Startups", "Film makers", "Architects", "Instagramers"],
    interval = window.setInterval(function() {
        cycleWords.innerHTML = words[wordsCnt | 0];      // take an integer value
        wordsCnt += Math.floor(wordsCnt) === 4 ? .1 : 1; // change speed for index 4
        wordsCnt %= words.length;                        // adjust length
    }, speed);
<div>Working with <span id="cycle-words">Copy writers</span></div>
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
  • And why should one do that? Just because you can? – Jonas Wilms Jul 12 '19 at 08:42
  • what do you have actually? – Nina Scholz Jul 12 '19 at 08:43
  • This site is the main ressource for many people to learn programming. We, and especially you as someone with outstanding coding skills, should always try to share best practices and propagate long-term working code. This answer is somewhat art, but rather belongs under "recreational code", I would certainly reject it in code-review, and I hope no one will push such code into production – Jonas Wilms Jul 12 '19 at 09:03
  • right, but then an answer would like this https://stackoverflow.com/questions/32081949/how-to-call-the-same-javascript-function-repeatedly-while-waiting-for-the-functi/32082676#32082676 and the answer would qualifies the question as duplicate. – Nina Scholz Jul 12 '19 at 09:12
  • Sure thats an answer worth linking (not necessarily a dupe, as the OP is probably not able to adapt that to his usecase). – Jonas Wilms Jul 12 '19 at 09:31
0

To sum up the requirements:

  1. do something at interval of half a second
  2. after 5 seconds
  3. wait for 5 seconds
  4. resume step 1

Proposed Solution:

setInterval to do the task every half second. After 5 seconds, clear the interval. Invoke the setInterval again after 5 seconds.

let counter = 0;

function resetInterval(){
    let x = setInterval(()=>{
        console.log(counter);
        counter++;
        if (counter % 10 === 0) {
            clearInterval(x);
            setTimeout(()=>{resetInterval()}, 5000);
        }
    }, 500);
}

resetInterval();
Chiranjib
  • 1,763
  • 2
  • 17
  • 29
-1

Consider using a recursive setTimeout instead - if the next index is 5, call the next setTimeout with 5000 instead of 500:

var speed = 500

var cycleWords = document.getElementById("cycle-words");
var wordsCnt = 0;
var words = [
  "Graphic designers",
  "Founders",
  "Photographers",
  "Copywriters",
  "Audio designers",
  "Startups",
  "Film makers",
  "Architects",
  "Instagramers"
];

const callback = () => {
  cycleWords.innerHTML = words[wordsCnt];
  wordsCnt = (wordsCnt + 1) % words.length;
  setTimeout(
    callback,
    wordsCnt == 5 ? 5000 : 500
  );
};
callback();
<div id="">
  Working with <span id="cycle-words">Copy writers</span></div>
</div>
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320