en Js, quiero intentar simular una tirada de dados mostrando imágenes de los dados 1 a 6, pero cuando trato de mostrarlas en un bucle for, solo muestra la imagen dado6. Intenté poner un bucle for anidado para ralentizar el bucle exterior, pero eso no funcionó. ¿La página necesita actualizarse después de cambiar el atributo "src"?
const dieImage = function (num) { return "images/dice" + String(num).trim() + ".png"; }; function dieRoll(num) { for (let i = 1; i < 7; i++) { for (let z = 0; z < 44444; z++) {} // attempt to slow if (num === 1) { img1.setAttribute("src", dieImage(i)); } else { img2.setAttribute("src", dieImage(i)); } } }Lo que te falta (más o menos) es que el navegador pinta la pantalla cuando el código JavaScript ha terminado de ejecutarse. Aunque esté configurando el atributo src en una imagen diferente en un bucle, el código JavaScript finaliza solo cuando finaliza el bucle. El navegador pinta solo una vez, es decir, la última imagen que configuró en el ciclo. Esta explicación puede ser demasiado simplificada, pero te da una idea.
La solución es volver desde el código JavaScript después de configurar el src y repetirlo después de un retraso adecuado, dando al usuario la oportunidad de sentir el cambio. setTimeout probablemente sea lo suficientemente bueno para su caso; en otros casos de uso en los que desea una animación realmente fluida, habría otras soluciones (por ejemplo requestAnimationFrame() ). Una implementación no probada para demostrar la intención:
function dieRoll(selectedNum) { var counter = 8; // how many times to change the die function repeat() { if (counter === 1) { // on the last iteration, set the image representing the selected number img1.setAttribute("src", dieImage(selectedNum)); } else { // else decrement the counter, set a random image and repeat after a timeout counter--; img1.setAttribute("src", dieImage(Math.floor(6 * Math.random()) + 1)); setTimeout(repeat, 300); } } repeat(); }Como se menciona en los comentarios, puede usar setTimeout . Puede introducir un retraso y darle al navegador la oportunidad de volver a dibujar usando setTimeout , promise y await , por ejemplo, así:
const DELAY = 300; // 300ms async function dieRoll(num) { for (let i = 1; i < 7; i++) { if (num === 1) { img1.setAttribute("src", dieImage(i)); } else { img2.setAttribute("src", dieImage(i)); } await new Promise((resolve) => setTimeout(() => resolve(), DELAY)); } } La ejecución del bucle se detendrá hasta que se resuelva la promesa, pero permitirá que el navegador continúe respondiendo y redibujando. Cuando la promesa se resuelve después de que se ejecuta la devolución de llamada de tiempo de espera después de los milisegundos DELAY dados, tendrá lugar la siguiente iteración del bucle.