Как установить временную задержку в javascript

У меня есть часть js на моем веб-сайте для переключения изображений, но вам нужна задержка, когда вы нажимаете изображение во второй раз. Задержка должна составлять 1000 мс. Итак, вы нажмете img.jpg, тогда появится img_onclick.jpg. Затем вы щелкнете изображение img_onclick.jpg, после чего должна появиться задержка в 1000 мс, прежде чем снова появится img.jpg.

Вот код:

jQuery(document).ready(function($) {

    $(".toggle-container").hide();
    $(".trigger").toggle(function () {
        $(this).addClass("active");
        $(".trigger").find('img').prop('src', 'http://localhost:8888/images/img_onclick.jpg');
    }, function () {
        $(this).removeClass("active");
        $(".trigger").find('img').prop('src', 'http://localhost:8888/images/img.jpg');
    });
    $(".trigger").click(function () {
        $(this).next(".toggle-container").slideToggle();
    });
});

Ответ 1

Используйте setTimeout():

var delayInMilliseconds = 1000; //1 second

setTimeout(function() {
  //your code to be executed after 1 second
}, delayInMilliseconds);

Если вы хотите сделать это без setTimeout: см. этот вопрос.

Ответ 2

setTimeout(function(){


}, 500); 

Поместите свой код внутри { }

500= 0,5 секунды

2200= 2,2 секунды

и др.

Ответ 3

Есть два (в основном используемых) типа функции таймера в javascript setTimeout и setInterval (другие)

Оба эти метода имеют одинаковую подпись. Они принимают функцию обратного вызова и время задержки в качестве параметра.

setTimeout выполняется только один раз после задержки, тогда как setInterval продолжает вызывать функцию обратного вызова после каждой задержки milisecs.

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

clearTimeout и clearInterval оба эти метода принимают целочисленный идентификатор, возвращаемый из вышеуказанных функций setTimeout и setInterval

Пример:

SetTimeout

alert("before setTimeout");

setTimeout(function(){
        alert("I am setTimeout");
   },1000); //delay is in milliseconds 

  alert("after setTimeout");

Если вы запустите приведенный выше код, вы увидите, что он предупреждает before setTimeout а затем, after setTimeout наконец, он предупреждает I am setTimeout через 1сек (1000 мс)

Из этого примера вы можете заметить, что setTimeout(...) является асинхронным, что означает, что он не ожидает истечения таймера, прежде чем перейти к следующему выражению, т.е. alert("after setTimeout");

Пример:

setInterval

alert("before setInterval"); //called first

 var tid = setInterval(function(){
        //called 5 times each time after one second  
      //before getting cleared by below timeout. 
        alert("I am setInterval");
   },1000); //delay is in milliseconds 

  alert("after setInterval"); //called second

setTimeout(function(){
     clearInterval(tid); //clear above interval after 5 seconds
},5000);

Если вы запустите приведенный выше код, вы увидите, что он предупреждает before setInterval а затем, after setInterval наконец, он предупреждает I am setInterval 5 раз через 1 с (1000 мс), потому что setTimeout очищает таймер через 5 секунд, иначе каждые 1 секунду вы будете предупреждены I am setInterval Бесконечно.

Как внутренний браузер это делает?

Я объясню вкратце.

Чтобы понять, что вы должны знать об очереди событий в JavaScript. В браузере реализована очередь событий. Всякий раз, когда событие запускается в js, все эти события (например, щелчок и т.д.) Добавляются в эту очередь. Когда вашему браузеру нечего выполнять, он берет событие из очереди и выполняет их одно за другим.

Теперь, когда вы вызываете setTimeout или setInterval ваш обратный вызов регистрируется таймером в браузере, и он добавляется в очередь событий по истечении заданного времени, и в конце концов javascript берет событие из очереди и выполняет его.

Это происходит так, потому что движок javascript однопоточный и может выполнять только одну вещь за раз. Таким образом, они не могут выполнять другой JavaScript и отслеживать ваш таймер. Вот почему эти таймеры регистрируются в браузере (браузер не является однопоточным), и он может отслеживать таймер и добавлять событие в очередь после истечения таймера.

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

Заметка

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

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

И, как я уже упоминал, javascript - это один поток. Так что, если вы заблокируете поток на долго.

Как этот код

while(true) { //infinite loop 
}

Ваш пользователь может получить сообщение о том, что страница не отвечает.

Ответ 4

ES-6 Solution

Ниже приведен пример кода, который использует aync/await для фактической задержки.

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

    async function delay(delayInms) {
      return new Promise(resolve  => {
        setTimeout(() => {
          resolve(2);
        }, delayInms);
      });
    }
    async function sample() {
      console.log('a');
      console.log('waiting...')
      let delayres = await delay(3000);
      console.log('b');
    }
    sample();

Ответ 5

Если вам нужно обновить, это еще одна возможность:

setTimeout(function () { 
    $("#jsSegurosProductos").jsGrid("refresh"); 
}, 1000);

Ответ 6

Я внесу свой вклад, потому что это помогает мне понять, что я делаю.

Чтобы сделать слайд-шоу с автоматической прокруткой, которое длится 3 секунды, я сделал следующее:

var isPlaying = true;

function autoPlay(playing){
   var delayTime = 3000;
   var timeIncrement = 3000;

   if(playing){
        for(var i=0; i<6; i++){//I have 6 images
            setTimeout(nextImage, delayTime);
            delayTime += timeIncrement;
        }
        isPlaying = false;

   }else{
       alert("auto play off");
   }
}

autoPlay(isPlaying);

Помните, что при выполнении setTimeout() вот так; он будет выполнять все функции времени ожидания, как если бы они выполнялись одновременно, предполагая, что в setTimeout (nextImage, delayTime) время задержки составляет статические 3000 миллисекунд.

Для этого я добавил дополнительные 3000 милли/с после каждого для увеличения цикла через delayTime += timeIncrement; ,

Для тех, кому все равно, вот как выглядит мой nextImage():

function nextImage(){
    if(currentImg === 1){//change to img 2
        for(var i=0; i<6; i++){
            images[i].style.zIndex = "0";
        }
        images[1].style.zIndex = "1";
        imgNumber.innerHTML = imageNumber_Text[1];
        imgDescription.innerHTML = imgDescText[1];

        currentImg = 2;
    }
    else if(currentImg === 2){//change to img 3
        for(var i=0; i<6; i++){
            images[i].style.zIndex = "0";
        }
        images[2].style.zIndex = "1";
        imgNumber.innerHTML = imageNumber_Text[2];
        imgDescription.innerHTML = imgDescText[2];

        currentImg = 3;
    }
    else if(currentImg === 3){//change to img 4
        for(var i=0; i<6; i++){
            images[i].style.zIndex = "0";
        }
        images[3].style.zIndex = "1";
        imgNumber.innerHTML = imageNumber_Text[3];
        imgDescription.innerHTML = imgDescText[3];

        currentImg = 4;
    }
    else if(currentImg === 4){//change to img 5
        for(var i=0; i<6; i++){
            images[i].style.zIndex = "0";
        }
        images[4].style.zIndex = "1";
        imgNumber.innerHTML = imageNumber_Text[4];
        imgDescription.innerHTML = imgDescText[4];

        currentImg = 5;
    }
    else if(currentImg === 5){//change to img 6
    for(var i=0; i<6; i++){
            images[i].style.zIndex = "0";
        }
        images[5].style.zIndex = "1";
        imgNumber.innerHTML = imageNumber_Text[5];
        imgDescription.innerHTML = imgDescText[5];

        currentImg = 6;
    }
    else if(currentImg === 6){//change to img 1
        for(var i=0; i<6; i++){
            images[i].style.zIndex = "0";
        }
        images[0].style.zIndex = "1";
        imgNumber.innerHTML = imageNumber_Text[0];
        imgDescription.innerHTML = imgDescText[0];

        currentImg = 1;
    }
}

Ответ 7

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

var delayInMilliseconds = 1000; 
setTimeout(function() {
 //add your code here to execute
 }, delayInMilliseconds);

Этот новый код приостановит его на 1 секунду и тем временем запустит ваш код.

Ответ 8

Для синхронизации вызовов вы можете использовать метод ниже:

function sleep(milliseconds) {
  var start = new Date().getTime();
  for (var i = 0; i < 1e7; i++) {
    if ((new Date().getTime() - start) > milliseconds){
      break;
    }
  }
}