¡Quiero agregar una clase a un div, de forma animada!
const divnew = document.createElement("div"); divnew.classList.add("circle"); const beans = document.getElementById("beans"); beans.append(divnew); divnew.classList.add("up"); .circle{ background:#FCD299; border-radius:50%; width:50px; height:50px; position:relative; top:300px; left: 500px; transition:all 300ms; } .circle.up{ position:relative; top:200px; left: 500px; } <div id="beans"></div> como puede ver, agrega una clase a un div, y luego quiero que agregue la clase up forma de animación. Pero no hace eso. ayuda
El navegador primero evalúa todo el javascript, y luego hace las cosas de CSS (probablemente pasando por alto algunos detalles, pero esa es la esencia básica). Entonces, el navegador solo ve un div con el circle y la clase up . Para solucionarlo, puede retrasar la configuración de la clase up , utilizando setTimeout de la siguiente manera:
const divnew = document.createElement("div"); divnew.classList.add("circle"); const beans = document.getElementById("beans"); beans.append(divnew); setTimeout(() => { divnew.classList.add("up") }, 0)Incluso si el tiempo de espera se establece en 0 ms, se envía a la cola de microtareas, que se evalúa más tarde y, por lo tanto, el CSS se actualiza y el navegador anima el elemento. Entonces obtienes la animación, pero aún sucede instantáneamente después de crear el div.
Debe usar requestAnimationFrame para permitir que el elemento se represente sin la clase de destino primero; de lo contrario, no sabe que necesita hacer la transición porque la primera vez que se representa no tiene "memoria" de no tener la clase.
const div = document.createElement("div"); div.classList.add("circle"); document.body.appendChild(div); window.requestAnimationFrame( () => div.classList.add("animate") ); .circle { background: #FCD299; border-radius: 50%; width: 50px; height: 50px; position: absolute; top: 0px; left: 0px; transition: all 3000ms; } .circle.animate { top: calc(100% - 50px); left: calc(100% - 50px); } Alternativamente, puede usar una animation CSS y definir @keyframes para su movimiento deseado en lugar de depender de una transition ; esto también evita la necesidad de JavaScript.
.circle { background: #FCD299; border-radius: 50%; width: 50px; height: 50px; position: absolute; animation: 3000ms forwards animate; } @keyframes animate { from { top: 0; left: 0; } to { top: calc(100% - 50px); left: calc(100% - 50px); } } <div class="circle"></div> (Tenga en cuenta que el animation-fill-mode es forwards , mantendrá el valor final de los atributos animados, en lugar de simplemente volver a desactivarse cuando finalice la animación)