Así que tengo un botón en el que quiero mostrar cada elemento de mi matriz durante unos segundos. Este es mi código html:

<button class="btn" id="random">Start</button>

Hice una matriz con jQuery que quiero usar para cambiar el texto de los botones:

$(document).ready(function() {
    $("#random").on("click", loop);
});

var array = ["el1","el2","el3"];

function loop() {
    for (i = 0; i < array.length; i++) {
        $("#random").html(array[i]);
    }
    var random = Math.floor(Math.random() * array.length) + 1;
    $("#random").html(array[random]);
}

Se supone que el bucle for hace lo que quiero, pero no puedo encontrar una manera de retrasar la velocidad, siempre muestra la última línea de código. Cuando intento setTimeout o algo así parece que se salta el bucle for.

2
nathalie 12 may. 2016 a las 21:15

3 respuestas

La mejor respuesta

Mi propuesta es usar IIFE y retraso:

var array = ["el1","el2","el3", "Start"];

function loop(){
  for (i = 0; i < array.length; i++){
    (function(i) {
      $("#random").delay(1000).queue(function () {
        $(this).html(array[i]);
        $(this).dequeue();
      });
    })(i);
  }
}


$(function () {
  $("#random").on("click", loop);
});
<script src="https://code.jquery.com/jquery-1.12.3.min.js"></script>

<button class="btn" id="random">Start</button>
1
gaetanoM 12 may. 2016 a las 18:46

Básicamente, un bucle for no te ayudará. Funciona con la velocidad máxima que puede. Y retrasarlo no sería bueno en js (simplemente congelaría el navegador). En cambio, solo puede hacer una función que se ejecutará con un retraso. Un poco de recursión, pero no del todo. A continuación haría el truco.

https://jsfiddle.net/7dryshay/

$(document).ready(function() {
    $("#random").on("click", function (event) {
    // texts to cycle
    var arr = ["el1","el2","el3"];

    // get the button elem (we need it in this scope)
    var $el = $(event.target);

    // iteation function (kinda recursive)
    var iter = function () {

      // no more stuff to display
      if (arr.length === 0) return;

      // get top of the array and set it on button
      $el.text(arr.shift());

      // proceed to next iteration
      setTimeout(iter, 500);
    }

    // start first iteration
    iter();
  });
});
0
pawel-kuznik 12 may. 2016 a las 18:32

Utilice setInterval() y clearInterval()

$(document).ready(
  function() {
    $("#random").on("click", loop);
  }
);

var array = ["el1", "el2", "el3"];
var int;

function loop() {
  var i = 0; // variable for array index
  int && clearInterval(int); // clear any previous interval
  int = setInterval(function() { //store interval reference for clearing
    if (i == array.length) clearInterval(int); // clear interval if reached the last index
    $("#random").text(i == array.length ? 'Start' : array[i++]); // update text with array element atlast set back to button text
  }, 1000);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<button class="btn" id="random">Start</button>

ACTUALIZACIÓN: si necesita implementarlo usando for bucle y setTimeout() luego haga algo como esto

var array = ["el1", "el2", "el3", "Start"];

function loop() {
  for (i = 0; i < array.length; i++) {
    (function(i) {
      setTimeout(function() {
        $("#random").html(array[i]);
      }, i * 1000);
    })(i);
  }
}


$(function() {
  $("#random").on("click", loop);
});
<script src="https://code.jquery.com/jquery-1.12.3.min.js"></script>

<button class="btn" id="random">Start</button>
1
Pranav C Balan 13 may. 2016 a las 03:01