es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Observador de intersección para múltiples videos en la misma página.

Tengo una página de portafolio hecha en WordPress y en la página tengo 5 videos que deben reproducirse cuando estén en el viewport y detenerse cuando estén fuera del viewport.

He utilizado el siguiente script que funciona sólo en el primer video de la página.

const video = document.querySelector(“video”);
let playState = null;
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (!entry.isIntersecting) {
video.pause();
playState = false;
} else {
video.play();
playState = true;
}
});
}, {});
observer.observe(video);
const onVisibilityChange = () => {
if (document.hidden || !playState) {
video.pause();
} else {
video.play();
}
};
document.addEventListener(“visibilitychange”, onVisibilityChange);
querySelector(“video”);

Y aquí está el enlace a la página:

Portfolio

Así que lo que quiero lograr es reproducir y detener cada video cuando está o no en el viewport.

Gracias.

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Para que este script funcione en los 5 videos de la página, es necesario modificarlo para que se dirija a todos los elementos de video y pase por cada uno de ellos individualmente. Aquí hay un ejemplo de cómo podría lograrlo:

    const videos = document.querySelectorAll("video");
    const playStates = new Array(videos.length).fill(null);
    
    const observer = new IntersectionObserver((entries) => {
      entries.forEach((entry, index) => {
        const video = videos[index];
        const playState = playStates[index];
    
        if (!entry.isIntersecting) {
          if (playState) {
            video.pause();
            playStates[index] = false;
          }
        } else {
          if (!playState) {
            video.play();
            playStates[index] = true;
          }
        }
      });
    }, {});
    
    videos.forEach((video) => {
      observer.observe(video);
      video.addEventListener("pause", () => {
        const index = Array.from(videos).indexOf(video);
        playStates[index] = false;
      });
    });
    
    const onVisibilityChange = () => {
      if (document.hidden) {
        videos.forEach((video) => {
          video.pause();
        });
    
        playStates.fill(false);
      } else {
        videos.forEach((video, index) => {
          if (!playStates[index]) {
            return;
          }
    
          const rect = video.getBoundingClientRect();
          if (rect.top <= window.innerHeight && rect.bottom >= 0) {
            video.play();
          } else {
            video.pause();
            playStates[index] = false;
          }
        });
      }
    };
    
    document.addEventListener("visibilitychange", onVisibilityChange);
    

    Este código primero selecciona todos los elementos de video y crea un array para llevar un seguimiento del estado de reproducción de cada video. Luego,configura un IntersectionObserver para detectar cuándo cada video entra o sale de la vista. Para cada entrada, se comprueba el estado actual de reproducción del video correspondiente y se pausa o reproduce según corresponda. Además, actualiza el array de estado de reproducción para cada video.

    Después de configurar el observador para cada video, el código escucha el evento pause en cada video para actualizar su estado de reproducción cuando se pausa directamente por el usuario.

    Finalmente, el código configura un evento visibilitychange para pausar todos los videos cuando la página está oculta (por ejemplo, cuando el usuario cambia a otra pestaña). Cuando la página vuelve a ser visible, comprueba el estado de la vista de cada video para determinar si debe reanudar la reproducción. Esta lógica asume que los videos que ya estaban reproduciéndose cuando la página estaba oculta deberían reanudar la reproducción cuando vuelva a ser visible.

Comments are closed.