Як встановити затримку в JavaScript


170

Я маю цю частину js на своєму веб-сайті для переключення зображень, але потрібна затримка, коли ви клацаєте зображення вдруге. Затримка повинна бути 1000мс. Отже, ви натиснете на img.jpg, тоді з'явиться img_onclick.jpg. Потім ви клацнете зображення img_onclick.jpg, тоді перед тим, як зобразити img.jpg, знову буде затримка на 1000 мс.

Ось код:

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();
    });
});

8
setTimeout(function(){/*YourCode*/},1000);
marteljn


можливо, шукаю, .stop()хоча. Подивіться тут api.jquery.com/stop
Марк Уолтерс

Відповіді:


380

Використання setTimeout():

var delayInMilliseconds = 1000; //1 second

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

Якщо ви хочете зробити це без setTimeout: зверніться до цього питання .


6
як це зробити синхронно? код всередині setTimeout не розпізнає властивості класу.
ishandutta2007

@ Ishandutta2007 побачити моя відповідь нижче -> stackoverflow.com/a/49813472/3919057
Ninjaneer

50
setTimeout(function(){


}, 500); 

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

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

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

тощо.


18

ES-6 Рішення

Нижче наведено зразок коду, який використовує aync / очікує фактичної затримки.

Існує багато обмежень, і це може бути не корисним, але просто розміщуйте тут для задоволення.

    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();


3
НЕ потрібно для delayфункції асинхронізації. Це дивовижне затягування працює, коли в тілі функції асинхронізації чекає Обіцяння, повернене звичайною функцією.
Intervoice

13

Є два (в основному використовувані) типи функції таймера в JavaScript setTimeoutта setInterval( інше )

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

setTimeoutвиконується лише один раз після затримки, тоді як setIntervalпродовжує викликати функцію зворотного виклику після кожної мілісекунди затримки.

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

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 мс), оскільки встановлене тайм-аут очистить таймер через 5 секунд, або ж кожні 1 секунду ви отримаєте попередження I am setIntervalнескінченно.

Як це робить браузер внутрішньо?

Я поясню коротко.

Щоб зрозуміти, що ви повинні знати про чергу подій у javascript. У браузері реалізована черга подій. Щоразу, коли подія запускається у js, усі ці події (наприклад, клацання тощо) додаються до цієї черги. Коли у вашому браузері немає нічого для виконання, він бере подію з черги та виконує їх по черзі.

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

Це трапляється так, тому що двигун javascript є однопоточним і вони можуть виконувати лише одне. Таким чином, вони не можуть виконувати інші javascript і слідкувати за вашим таймером. Ось чому ці таймери зареєстровані в браузері (браузер не є однопоточним), і він може відслідковувати таймер і додавати події в чергу після закінчення таймера.

те саме відбувається setIntervalлише в цьому випадку, подія додається до черги знову і знову через вказаний інтервал, поки не буде очищено або оновлена ​​сторінка браузера.

Примітка

Параметр затримки, який ви передаєте цим функціям, - це мінімальний час затримки для виконання зворотного дзвінка. Це тому, що після закінчення таймера браузер додає подію до черги, яку повинен виконувати механізм javascript, але виконання зворотного виклику залежить від вашої позиції подій у черзі, і оскільки двигун є однопоточним, він виконуватиме всі події в черга одна за одною.

Отже, зворотний виклик може колись зайняти більше, ніж зазначений час затримки, щоб викликати спеціально, коли ваш інший код блокує потік і не дає йому часу обробляти те, що є в черзі.

І як я вже згадував, JavaScript - це один потік Отже, якщо ви блокуєте нитку надовго.

Як і цей код

while(true) { //infinite loop 
}

Ваш користувач може отримати повідомлення про те, що сторінка з повідомленням не відповідає .


1
Чи можете ви сказати мені, як я можу зупинити асинхронну поведінку setTimeout ()?
Чандан Пурбія

Ви не використовуєте, setTimeoutякщо не хочете асинхронної поведінки.
Надір Ласкар

5

Для синхронізації дзвінків ви можете скористатися наведеним нижче способом:

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

0

Якщо вам потрібно оновити, це ще одна можливість:

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

0

Ось що я роблю для вирішення цього питання. Я погоджуюсь, що це пов'язано з проблемою часу і для виконання коду потрібна пауза.

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

Цей новий код призупинить його на 1 секунду і тим часом запустить ваш код.


0

Я дам свій внесок, тому що це допомагає мені зрозуміти, що я роблю.

Щоб зробити слайд-шоу з автоматичною прокруткою, яке триває 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;.

Для тих, хто тут хвилює, як виглядає мій наступний малюнок ():

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;
    }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.