Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

235
Visualizações
Problema con el uso de IntersectionObserver para activar la animación CSS

Estoy tratando de usar IntersectionObserver para observar el container 3 para que la animación wipe-enter comience cuando estén dentro de la ventana gráfica uno por uno.

Si me desplazo a un container (que está fuera de la ventana gráfica) lentamente para que solo una parte esté dentro de la ventana gráfica, el container sigue parpadeando hasta que está completamente dentro de la ventana gráfica.

Traté de inspeccionar el container cuando parpadea y parece que la clase container-animation se agrega y elimina constantemente hasta que el container está completamente dentro de la ventana gráfica.

Esta es la primera vez que uso IntersectionObserver, por lo que no estoy seguro de cómo se debe cambiar el código para que dejen de parpadear.

Cualquier ayuda será apreciada. Gracias.

 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Animation</title> <style> .container { width: 300px; height: 300px; background: green; margin: 500px auto; } @keyframes wipe-enter { 0% { transform: scale(0, .025); } 50% { transform: scale(1, .025); } } .container-animation { animation: wipe-enter 1s 1; } </style> </head> <body> <div class="container"></div> <div class="container"></div> <div class="container"></div> </body> <script> // Register IntersectionObserver const io = new IntersectionObserver(entries => { entries.forEach(entry => { // Add 'container-animation' class if observation target is inside viewport if (entry.intersectionRatio > 0) { entry.target.classList.add('container-animation'); } else { // Remove 'container-animation' class entry.target.classList.remove('container-animation'); } }) }) // Declares what to observe, and observes its properties. const containers = document.querySelectorAll('.container'); containers.forEach((el) => { io.observe(el); }) </script> </html>

about 4 years ago · Juan Pablo Isaza
2 Respostas
Responde à pergunta

0

Cuando se escala un elemento, aún "ocupa" el mismo espacio en la página, en el sentido de que otros elementos no se ven afectados. Sin embargo, el escalado se realiza por defecto desde el punto central del elemento.

Entonces, cuando un elemento ingresa a la ventana gráfica, su código lo escala inmediatamente hacia abajo y luego aumenta gradualmente su altura, pero desde el centro, que en ese momento estará casi 150 px debajo (o arriba) de la parte inferior / superior de la ventana gráfica.

Así que te dicen que se ha ido de la ventana gráfica y quitas la animación. El elemento vuelve a tener una altura de 300 px y, por lo tanto, ingresa a la ventana gráfica y así sucesivamente. Por lo tanto, 'parpadeo'.

Una forma de evitar esto es no eliminar la animación cuando el elemento sale de la ventana gráfica, pero cuando la animación ha terminado, entonces no importa que se haya reducido a través de la escala y no esté en la ventana gráfica durante parte de un segundo. .

Pero, para evitar que otros elementos se muevan, no podemos hacer esto simplemente cambiando la altura del elemento, que debe permanecer constante. Este código escala un pseudo elemento anterior en cada uno de los contenedores.

 <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Animation</title> <style> .container { width: 300px; height: 300px; margin: 500px auto; position: relative; } @keyframes wipe-enter { 0% { transform: scale(0, .025); } 50% { transform: scale(1, .025); } 100% { transform: scale(1, 1); } } .container::before { content: ''; position: absolute; width: 100%; height: 100%; left: 0; top: 0; background: green; } .container.container-animation::before { animation: wipe-enter 1s 1; } </style> </head> <body> <div class="container"></div> <div class="container"></div> <div class="container"></div> </body> <script> // Register IntersectionObserver const io = new IntersectionObserver(entries => { entries.forEach(entry => { // Add 'container-animation' class if observation target is inside viewport if (entry.intersectionRatio > 0) { entry.target.classList.add('container-animation'); } }) }) // Declares what to observe, and observes its properties. const containers = document.querySelectorAll('.container'); containers.forEach((el) => { io.observe(el); el.addEventListener('animationend', function () { el.classList.remove('container-animation'); }); }) </script> </html>
about 4 years ago · Juan Pablo Isaza Relatório

0

Aquí hay una solución después de leer la respuesta de A Haworth. También cambié la opacidad para que el contenedor no se muestre inicialmente.

 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Animation</title> <style> .container { width: 300px; height: 300px; background: green; margin: 500px auto; opacity: 0; } @keyframes wipe-enter { 0% { transform: scale(0, .025); } 50% { transform: scale(1, .025); } 100% { opacity: 1; } } .container-animation { animation: wipe-enter 1s 1; animation-fill-mode: forwards; } </style> </head> <body> <div class="container-wrapper"> <div class="container"></div> </div> <div class="container-wrapper"> <div class="container"></div> </div> <div class="container-wrapper"> <div class="container"></div> </div> </body> <script> // Register IntersectionObserver const io = new IntersectionObserver(entries => { entries.forEach(entry => { const container = entry.target.querySelector('.container'); console.log(entry) // Add 'container-animation' class if observation target is inside viewport if (entry.intersectionRatio > 0) { container.classList.add('container-animation'); } else { // Remove 'container-animation' class container.classList.remove('container-animation'); } }) }) // Declares what to observe, and observes its properties. const containers = document.querySelectorAll('.container-wrapper'); containers.forEach((el) => { io.observe(el); }) </script> </html>

about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda