如何在javascript中设置时间延迟

时间:2021-01-13 01:19:20

I have this a piece of js in my website to switch images but need a delay when you click the image a second time. The delay should be 1000ms. So you would click the img.jpg then the img_onclick.jpg would appear. You would then click the img_onclick.jpg image there should then be a delay of 1000ms before the img.jpg is shown again.

我有一个js在我的网站切换图片,但是当你再次点击图片时需要延迟。延迟应该是1000ms。你可以点击img.jpg然后img_onclick.jpg就会出现。然后单击img_onclick.jpg图像,在img.jpg再次显示之前,应该有1000ms的延迟。

Here is the code:

这是代码:

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

6 个解决方案

#1


236  

Use setTimeout():

使用setTimeout():

var delayInMilliseconds = 1000; //1 second

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

If you want to do it without setTimeout: Refer to this question.

如果您想在不设置setTimeout的情况下进行此操作,请参考这个问题。

#2


31  

setTimeout(function(){


}, 500); 

Place your code inside of the { }

将代码放在{}内

500 = 0.5 seconds

500 = 0.5秒

2200 = 2.2 seconds

2200 = 2.2秒

etc.

等。

#3


4  

There are two (mostly used) types of timer function in javascript setTimeout and setInterval (other)

在javascript setTimeout和setInterval(其他)中,有两种(主要使用)定时器函数类型

Both these methods have same signature. They take a call back function and delay time as parameter.

这两种方法都有相同的签名。它们以回调函数和延迟时间作为参数。

setTimeout executes only once after the delay whereas setInterval keeps on calling the callback function after every delay milisecs.

setTimeout只在延迟之后执行一次,而setInterval在每次延迟毫秒后继续调用回调函数。

both these methods returns an integer identifier that can be used to clear them before the timer expires.

这两个方法都返回一个整数标识符,可用于在计时器过期之前清除它们。

clearTimeout and clearInterval both these methods take an integer identifier returned from above functions setTimeout and setInterval

clearTimeout和clearInterval这两种方法都采用从上述函数setTimeout和setInterval返回的整数标识符

Example:

例子:

setTimeout

setTimeout

alert("before setTimeout");

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

  alert("after setTimeout");

If you run the the above code you will see that it alerts before setTimeout and then after setTimeout finally it alerts I am setTimeout after 1sec (1000ms)

如果你运行上面的代码,你会看到它会在setTimeout之前发出警报然后在setTimeout之后发出警报最后它会在1秒(1000ms)之后发出警报

What you can notice from the example is that the setTimeout(...) is asynchronous which means it doesn't wait for the timer to get elapsed before going to next statement i.e alert("after setTimeout");

您可以从示例中注意到,setTimeout(…)是异步的,这意味着它不会等待计时器超时,然后再转到下一个语句i。e警报(“后setTimeout”);

Example:

例子:

setInterval

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

If you run the the above code you will see that it alerts before setInterval and then after setInterval finally it alerts I am setInterval 5 times after 1sec (1000ms) because the setTimeout clear the timer after 5 seconds or else every 1 second you will get alert I am setInterval Infinitely.

如果你运行上面的代码,你会看到它之前提醒setInterval之后setInterval最后警告我setInterval 5次后1秒(1000毫秒)因为setTimeout清除计时器后5秒,否则每1秒你就会提醒我setInterval无限。

How browser internally does that?

浏览器内部如何做到这一点?

I will explain in brief.

我将简要地解释一下。

To understand that you have to know about event queue in javascript. There is a event queue implemented in browser. Whenever an event get triggered in js, all of these events (like click etc.. ) are added to this queue. When your browser has nothing to execute it takes an event from queue and executes them one by one.

要理解这一点,您必须了解javascript中的事件队列。浏览器中实现了一个事件队列。当一个事件在js中被触发时,所有这些事件(如单击等)添加到此队列。当您的浏览器没有任何要执行的东西时,它会从队列中取出一个事件并逐个执行它们。

Now, when you call setTimeout or setInterval your callback get registered to an timer in browser and it gets added to the event queue after the given time expires and eventually javascript takes the event from the queue and executes it.

现在,当您调用setTimeout或setInterval时,您的回调会在浏览器中注册到一个计时器,并在给定的时间过期后添加到事件队列中,最终javascript从队列中获取事件并执行它。

This happens so, because javascript engine are single threaded and they can execute only one thing at a time. So, they cannot execute other javascript and keep track of your timer. That is why these timers are registered with browser (browser are not single threaded) and it can keep track of timer and add an event in the queue after the timer expires.

因为javascript引擎是单线程的,它们一次只能执行一件事情。因此,它们不能执行其他javascript并跟踪您的计时器。这就是为什么这些计时器被浏览器注册(浏览器不是单线程的),它可以跟踪计时器并在计时器过期后在队列中添加事件。

same happens for setInterval only in this case the event is added to the queue again and again after the specified interval until it gets cleared or browser page refreshed.

只有在这种情况下,setInterval也会发生同样的情况,即事件在指定的间隔之后一次又一次地添加到队列中,直到它被清除或刷新浏览器页面为止。

Note

请注意

The delay parameter you pass to these functions is the minimum delay time to execute the callback. This is because after the timer expires the browser adds the event to the queue to be executed by the javascript engine but the execution of the callback depends upon your events position in the queue and as the engine is single threaded it will execute all the events in the queue one by one.

您传递给这些函数的延迟参数是执行回调的最小延迟时间。这是因为计时器到期后浏览器将事件添加到队列执行的javascript引擎,但回调的执行取决于你的活动在队列中的位置和引擎是单线程将执行队列中的所有事件。

Hence, your callback may sometime take more than the specified delay time to be called specially when your other code blocks the thread and not giving it time to process what's there in the queue.

因此,您的回调有时可能会花费比指定的延迟时间更多的时间来调用,特别是当您的其他代码阻塞了线程并且没有给它时间来处理队列中的内容时。

And as I mentioned javascript is single thread. So, if you block the thread for long.

正如我提到的,javascript是一个线程。如果你长时间地阻塞线程。

Like this code

这样的代码

while(true) { //infinite loop 
}

Your user may get a message saying page not responding.

您的用户可能会收到一条消息说页面没有响应。

#4


3  

Below is a sample code which uses aync/await to have an actual delay.

下面是一个示例代码使用aync /等待有一个实际的延迟。

There are many constraints and this may not be useful, but just posting here for fun..

有很多限制,这可能没有用处,但只是为了好玩在这里发布。

    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


0  

If you need refresh, this is another posibility:

如果你需要刷新,这是另一个可能性:

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

#6


0  

I'll give my input because it helps me understand what im doing.

我给我的输入,因为它帮助我理解我做什么。

to make an auto scrolling slide show that has a 3 second wait I did the following:

为了制作一个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);

Remember that when executing setTimeout() like this; it will execute all time out functions as if they where executed at the same time assuming that in setTimeout(nextImage, delayTime);delay time is a static 3000 milliseconds.

记住,当像这样执行setTimeout()时;它将执行所有的超时功能,就好像它们同时执行了setTimeout(nextImage, delayTime);延迟时间是静态的3000毫秒。

What I did to account for this was add an extra 3000 milli/s after each for loop incrementation via delayTime += timeIncrement;.

我所做的就是在每次循环增量之后通过delayTime += timeIncrement添加3000毫/s;

for those who care here is what my nextImage() looks like:

对于那些关心我的下一个时代的人来说:

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

#1


236  

Use setTimeout():

使用setTimeout():

var delayInMilliseconds = 1000; //1 second

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

If you want to do it without setTimeout: Refer to this question.

如果您想在不设置setTimeout的情况下进行此操作,请参考这个问题。

#2


31  

setTimeout(function(){


}, 500); 

Place your code inside of the { }

将代码放在{}内

500 = 0.5 seconds

500 = 0.5秒

2200 = 2.2 seconds

2200 = 2.2秒

etc.

等。

#3


4  

There are two (mostly used) types of timer function in javascript setTimeout and setInterval (other)

在javascript setTimeout和setInterval(其他)中,有两种(主要使用)定时器函数类型

Both these methods have same signature. They take a call back function and delay time as parameter.

这两种方法都有相同的签名。它们以回调函数和延迟时间作为参数。

setTimeout executes only once after the delay whereas setInterval keeps on calling the callback function after every delay milisecs.

setTimeout只在延迟之后执行一次,而setInterval在每次延迟毫秒后继续调用回调函数。

both these methods returns an integer identifier that can be used to clear them before the timer expires.

这两个方法都返回一个整数标识符,可用于在计时器过期之前清除它们。

clearTimeout and clearInterval both these methods take an integer identifier returned from above functions setTimeout and setInterval

clearTimeout和clearInterval这两种方法都采用从上述函数setTimeout和setInterval返回的整数标识符

Example:

例子:

setTimeout

setTimeout

alert("before setTimeout");

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

  alert("after setTimeout");

If you run the the above code you will see that it alerts before setTimeout and then after setTimeout finally it alerts I am setTimeout after 1sec (1000ms)

如果你运行上面的代码,你会看到它会在setTimeout之前发出警报然后在setTimeout之后发出警报最后它会在1秒(1000ms)之后发出警报

What you can notice from the example is that the setTimeout(...) is asynchronous which means it doesn't wait for the timer to get elapsed before going to next statement i.e alert("after setTimeout");

您可以从示例中注意到,setTimeout(…)是异步的,这意味着它不会等待计时器超时,然后再转到下一个语句i。e警报(“后setTimeout”);

Example:

例子:

setInterval

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

If you run the the above code you will see that it alerts before setInterval and then after setInterval finally it alerts I am setInterval 5 times after 1sec (1000ms) because the setTimeout clear the timer after 5 seconds or else every 1 second you will get alert I am setInterval Infinitely.

如果你运行上面的代码,你会看到它之前提醒setInterval之后setInterval最后警告我setInterval 5次后1秒(1000毫秒)因为setTimeout清除计时器后5秒,否则每1秒你就会提醒我setInterval无限。

How browser internally does that?

浏览器内部如何做到这一点?

I will explain in brief.

我将简要地解释一下。

To understand that you have to know about event queue in javascript. There is a event queue implemented in browser. Whenever an event get triggered in js, all of these events (like click etc.. ) are added to this queue. When your browser has nothing to execute it takes an event from queue and executes them one by one.

要理解这一点,您必须了解javascript中的事件队列。浏览器中实现了一个事件队列。当一个事件在js中被触发时,所有这些事件(如单击等)添加到此队列。当您的浏览器没有任何要执行的东西时,它会从队列中取出一个事件并逐个执行它们。

Now, when you call setTimeout or setInterval your callback get registered to an timer in browser and it gets added to the event queue after the given time expires and eventually javascript takes the event from the queue and executes it.

现在,当您调用setTimeout或setInterval时,您的回调会在浏览器中注册到一个计时器,并在给定的时间过期后添加到事件队列中,最终javascript从队列中获取事件并执行它。

This happens so, because javascript engine are single threaded and they can execute only one thing at a time. So, they cannot execute other javascript and keep track of your timer. That is why these timers are registered with browser (browser are not single threaded) and it can keep track of timer and add an event in the queue after the timer expires.

因为javascript引擎是单线程的,它们一次只能执行一件事情。因此,它们不能执行其他javascript并跟踪您的计时器。这就是为什么这些计时器被浏览器注册(浏览器不是单线程的),它可以跟踪计时器并在计时器过期后在队列中添加事件。

same happens for setInterval only in this case the event is added to the queue again and again after the specified interval until it gets cleared or browser page refreshed.

只有在这种情况下,setInterval也会发生同样的情况,即事件在指定的间隔之后一次又一次地添加到队列中,直到它被清除或刷新浏览器页面为止。

Note

请注意

The delay parameter you pass to these functions is the minimum delay time to execute the callback. This is because after the timer expires the browser adds the event to the queue to be executed by the javascript engine but the execution of the callback depends upon your events position in the queue and as the engine is single threaded it will execute all the events in the queue one by one.

您传递给这些函数的延迟参数是执行回调的最小延迟时间。这是因为计时器到期后浏览器将事件添加到队列执行的javascript引擎,但回调的执行取决于你的活动在队列中的位置和引擎是单线程将执行队列中的所有事件。

Hence, your callback may sometime take more than the specified delay time to be called specially when your other code blocks the thread and not giving it time to process what's there in the queue.

因此,您的回调有时可能会花费比指定的延迟时间更多的时间来调用,特别是当您的其他代码阻塞了线程并且没有给它时间来处理队列中的内容时。

And as I mentioned javascript is single thread. So, if you block the thread for long.

正如我提到的,javascript是一个线程。如果你长时间地阻塞线程。

Like this code

这样的代码

while(true) { //infinite loop 
}

Your user may get a message saying page not responding.

您的用户可能会收到一条消息说页面没有响应。

#4


3  

Below is a sample code which uses aync/await to have an actual delay.

下面是一个示例代码使用aync /等待有一个实际的延迟。

There are many constraints and this may not be useful, but just posting here for fun..

有很多限制,这可能没有用处,但只是为了好玩在这里发布。

    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


0  

If you need refresh, this is another posibility:

如果你需要刷新,这是另一个可能性:

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

#6


0  

I'll give my input because it helps me understand what im doing.

我给我的输入,因为它帮助我理解我做什么。

to make an auto scrolling slide show that has a 3 second wait I did the following:

为了制作一个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);

Remember that when executing setTimeout() like this; it will execute all time out functions as if they where executed at the same time assuming that in setTimeout(nextImage, delayTime);delay time is a static 3000 milliseconds.

记住,当像这样执行setTimeout()时;它将执行所有的超时功能,就好像它们同时执行了setTimeout(nextImage, delayTime);延迟时间是静态的3000毫秒。

What I did to account for this was add an extra 3000 milli/s after each for loop incrementation via delayTime += timeIncrement;.

我所做的就是在每次循环增量之后通过delayTime += timeIncrement添加3000毫/s;

for those who care here is what my nextImage() looks like:

对于那些关心我的下一个时代的人来说:

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