Изменение времени setinterval после его запуска

У меня есть функция setInterval, которая изменяет элементы innerHTML из массива каждые полсекунды. Я хотел бы показать пятый элемент в течение 5 секунд, но затем возобновлять setInterval каждые полсекунды.

Я попытался изменить скорость во время 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>

Скорость остается прежней.

функция цикл() { ...; setTimeout (цикл, скорость); }

user2039981 12.07.2019 10:35

Возможный дубликат Изменение интервала SetInterval во время его работы

showdev 12.07.2019 10:36

вы можете использовать ленивый подход и добавлять столько одинаковых элементов, пока не получите желаемую длину отображения одного и того же слова...

Nina Scholz 12.07.2019 10:38
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
3
52
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Ответ принят как подходящий

setInterval будет продолжать работать со значениями, переданными в качестве аргументов, это невозможно изменить. Вы можете отменить интервал и создать новый, но в этом случае имеет смысл начинать новый тайм-аут с setTimeout всякий раз, когда заканчивается предыдущий.

// 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>

спасибо за добавление комментариев, очень полезно :)

user1059511 12.07.2019 10:57

Рад помочь :)

Jonas Wilms 12.07.2019 10:58

Вместо этого рассмотрите возможность использования рекурсивного setTimeout - если следующий индекс равен 5, вызовите следующий setTimeout с 5000 вместо 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>

Вы можете использовать setTimeout вместо установленного временного интервала. Здесь код, который вы можете использовать

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.info() requires firebug    
setDeceleratingTimeout(function(){ console.info('hi'); }, 10, 10);
setDeceleratingTimeout(function(){ console.info('bye'); }, 100, 10);

Вы можете изменить количество слов для индекса 4 и добавить за цикл только 0.1 вместо одного.

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>

А зачем это делать? Только потому, что ты можешь?

Jonas Wilms 12.07.2019 10:42

что у тебя на самом деле?

Nina Scholz 12.07.2019 10:43

Этот сайт является основным ресурсом для многих людей, желающих научиться программированию. Мы, и особенно вы, как человек с выдающимися навыками кодирования, всегда должны стараться делиться передовым опытом и распространять долгосрочный рабочий код. Этот ответ в некоторой степени является искусством, но скорее относится к «развлекательному коду», я бы, конечно, отклонил его при проверке кода, и я надеюсь, что никто не будет запускать такой код в производство.

Jonas Wilms 12.07.2019 11:03

правильно, но тогда ответ будет похож на этот stackoverflow.com/questions/32081949/…, и ответ будет квалифицировать вопрос как дубликат.

Nina Scholz 12.07.2019 11:12

Конечно, это ответ, который стоит связать (не обязательно обман, поскольку ОП, вероятно, не сможет адаптировать это к своему варианту использования).

Jonas Wilms 12.07.2019 11:31

Резюмируя требования:

  1. делать что-либо с интервалом в полсекунды
  2. через 5 секунд
  3. подождите 5 секунд
  4. возобновить шаг 1

Предложенное решение:

setInterval для выполнения задачи каждые полсекунды. Через 5 секунд очистите интервал. Снова вызовите setInterval через 5 секунд.

let counter = 0;

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

resetInterval();

Другие вопросы по теме