Como definir o atraso no javascript

170

Eu tenho isso um pedaço de js no meu site para alternar imagens, mas preciso de um atraso quando você clica na imagem uma segunda vez. O atraso deve ser de 1000 ms. Então você clicaria no img.jpg e o img_onclick.jpg apareceria. Você clicaria na imagem img_onclick.jpg e, em seguida, deveria haver um atraso de 1000ms antes que o img.jpg fosse exibido novamente.

Aqui está o código:

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();
    });
});
Azul Laranja
fonte
8
setTimeout(function(){/*YourCode*/},1000);
26813 marteljn
possivelmente procurando .stop()embora. Dê uma olhada aqui api.jquery.com/stop #
Mark Walters
Possível duplicata de Put a Delay in Javascript
Anônimo

Respostas:

380

Use setTimeout():

var delayInMilliseconds = 1000; //1 second

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

Se você quiser fazê-lo sem setTimeout: Consulte esta pergunta .

HIRA THAKUR
fonte
6
como fazê-lo de forma síncrona? código dentro de setTimeout não reconhece propriedades de classe.
precisa saber é o seguinte
@ ishandutta2007 ver minha resposta abaixo -> stackoverflow.com/a/49813472/3919057
Ninjaneer
50
setTimeout(function(){


}, 500); 

Coloque seu código dentro do { }

500 = 0,5 segundos

2200 = 2,2 segundos

etc.

maudulus
fonte
18

Solução ES-6

Abaixo está um código de exemplo que usa aync / waitit para ter um atraso real.

Existem muitas restrições e isso pode não ser útil, mas basta postar aqui por diversão ..

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

Ninjaneer
fonte
3
NÃO é necessário que a delayfunção seja assíncrona. Esse atraso impressionante funciona quando uma promessa retornada por uma função regular é aguardada no corpo de uma função assíncrona.
Intervoice
13

Existem dois tipos (mais usados) de função de timer em javascript setTimeoute setInterval( outros )

Ambos os métodos têm a mesma assinatura. Eles recebem uma função de retorno de chamada e atrasam o tempo como parâmetro.

setTimeoutexecuta apenas uma vez após o atraso, enquanto setIntervalcontinua chamando a função de retorno de chamada após cada milissegundo de atraso.

esses dois métodos retornam um identificador inteiro que pode ser usado para limpá-los antes que o cronômetro expire.

clearTimeoute clearIntervalambos os métodos usam um identificador inteiro retornado das funções acima setTimeoutesetInterval

Exemplo:

setTimeout

alert("before setTimeout");

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

  alert("after setTimeout");

Se você executar o código acima, verá que ele alerta before setTimeoute, after setTimeoutfinalmente, I am setTimeoutdepois de 1 segundo (1000ms)

O que você pode notar no exemplo é que o setTimeout(...)é assíncrono, o que significa que não espera o tempo decorrido antes de passar para a próxima instrução.alert("after setTimeout");

Exemplo:

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

Se você executar o código acima, verá que ele alerta before setIntervale, after setIntervalfinalmente, alerta I am setInterval 5 vezes após 1 segundo (1000ms), porque o setTimeout limpa o timer após 5 segundos ou, a cada 1 segundo, você recebe um alertaI am setInterval infinitamente.

Como o navegador faz isso internamente?

Vou explicar em breve.

Para entender que você precisa saber sobre a fila de eventos em javascript. Há uma fila de eventos implementada no navegador. Sempre que um evento é acionado em js, todos esses eventos (como clique etc.) são adicionados a essa fila. Quando o seu navegador não tem nada para executar, ele pega um evento da fila e os executa um por um.

Agora, quando você liga setTimeoutousetInterval seu retorno de chamada é registrado em um timer no navegador, ele é adicionado à fila de eventos após o tempo determinado expirar e, eventualmente, o javascript pega o evento da fila e o executa.

Isso acontece assim, porque o mecanismo javascript é thread único e eles podem executar apenas uma coisa de cada vez. Portanto, eles não podem executar outro javascript e acompanhar o seu cronômetro. É por isso que esses timers são registrados no navegador (o navegador não possui thread único) e ele pode acompanhar o cronômetro e adicionar um evento na fila após o término do cronômetro.

O mesmo acontece setIntervalapenas neste caso, o evento é adicionado à fila repetidamente após o intervalo especificado até que seja limpo ou a página do navegador atualizada.

Nota

O parâmetro de atraso que você passa para essas funções é o tempo mínimo de atraso para executar o retorno de chamada. Isso ocorre porque, após o tempo expirar, o navegador adiciona o evento à fila a ser executada pelo mecanismo javascript, mas a execução do retorno de chamada depende da posição de seus eventos na fila e, como o mecanismo é único, ele executará todos os eventos em a fila um por um.

Portanto, seu retorno de chamada pode demorar um pouco mais do que o tempo de atraso especificado para ser chamado especialmente quando seu outro código bloqueia o encadeamento e não dá tempo para processar o que há na fila.

E como eu mencionei, o javascript é de thread único. Portanto, se você bloquear o encadeamento por muito tempo.

Como este código

while(true) { //infinite loop 
}

Seu usuário pode receber uma mensagem informando que a página não está respondendo .

Nadir Laskar
fonte
1
Você pode me dizer como posso parar o comportamento assíncrono de setTimeout ()?
Chandan Purbia
Você não usa setTimeoutse não deseja comportamento assíncrono.
Nadir Laskar
5

Para chamadas de sincronização, você pode usar o método abaixo:

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

Se você precisar de atualização, essa é outra possibilidade:

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

Aqui está o que estou fazendo para resolver esse problema. Concordo que isso ocorre por causa do problema de tempo e precisava de uma pausa para executar o código.

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

Este novo código o pausará por 1 segundo e, enquanto isso, executará seu código.

Amir Md Amiruzzaman
fonte
0

Vou dar minha opinião, porque isso me ajuda a entender o que estou fazendo.

Para fazer uma apresentação de slides de rolagem automática com uma espera de 3 segundos, fiz o seguinte:

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

Lembre-se que ao executar setTimeout () assim; ele executará todas as funções de tempo limite como se fossem executadas ao mesmo tempo, assumindo que em setTimeout (nextImage, delayTime), o tempo de atraso é de 3000 milissegundos estáticos.

O que eu fiz para explicar isso foi adicionar mais 3000 mili / s após cada um para incrementar o loop via delayTime += timeIncrement;.

Para quem se importa aqui, é como minha nextImage () se parece:

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