A煤n no tienes acceso a esta clase

Crea una cuenta y contin煤a viendo este curso

IntersectionObserver

21/42
Recursos

Sirve para observar elementos y si cruzan un umbral que nosotros definimos nos lo va a notificar para tomar acci贸n.

El umbral se define por el porcentaje que tiene intersecci贸n con el viewport, con la parte visible de nuestra p谩gina.

Aportes 130

Preguntas 37

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad? Crea una cuenta o inicia sesi贸n.

Apuntes de esta clase:

Si les cuesta un poco la parte de this, b谩sicamente esta pasando lo siguiente:

Si les interesa entender m谩s sobre el tema, escrib铆 un art铆culo al respecto: https://filisantillan.com/this-en-diferentes-situaciones-y-su-comportamiento

Intersection Observer API

La API Observador de Intersecci贸n, provee una v铆a para, de forma as铆ncrona, observar cambios en la intersecci贸n de un elemento con un elemento ancestro o con el viewport del documento de nivel superior.

La informaci贸n sobre intersecci贸n es necesaria por muchas razones, tales como:

  • Lazy-loading de im谩genes u otro contenido a medida que la p谩gina se desplaza.
  • Implementaci贸n de 鈥渟croll infinito鈥 de sitios web, donde m谩s y m谩s contenido se carga y muestra a medida que usted hace scroll, de forma que el usuario no tiene que pasar p谩ginas.
  • Informes de visualizaciones de anuncios para calcular ingresos por publicidad.
  • Decidir si deben realizarse tareas o procesos de animaci贸n basados en si el usuario ver谩 o no el resultado.

Creando un intersection observer

Crear el intersection observer llamando a su constructor y pas谩ndole una funci贸n callback para que se ejecute cuando un nivel (threshold) sea cruzado en una u otra direcci贸n:

var options = {
  root: document.querySelector('#scrollArea'),
  rootMargin: '0px',
  threshold: 1.0
}

var observer = new IntersectionObserver(callback, options);

Un threshold de 1.0 significa que cuando el 100% del elemento target est谩 visible dentro del elemento especificado por la opci贸n root, la funci贸n callback es invocada.

Opciones de Intersection observer

El objeto options pasado al constructor IntersectionObserver() le deja controlar las circunstancias bajo las cuales la funci贸n callback del observer es invocada. Tiene los siguientes campos:

root

El elemento que es usado como viewport para comprobar la visibilidad de elemento target. Debe ser un elemento ascendiente del target. Por defecto se toma el viewport del navegador si no se especifica o si se especifica como null.

rootMargin

Margen alrededor del elemeto root. Puede tener valores similares a los de CSS margin property, e.g. "10px 20px 30px 40px" (top, right, bottom, left). Los valores pueden ser porcentajes. Este conjunto de valores sirve para aumentar o encoger cada lado del cuadro delimitador del elemento root antes de calcular las intersecciones. Por defecto son todos cero.

threshold

Es un n煤mero o un array de n煤meros que indican a que porcentaje de visibilidad del elemento target, la funci贸n callback del observer deber铆a ser ejecutada. Si usted quiere que se detecte cuando la visibilidad pasa la marca del 50%, deber铆a usar un valor de 0.5. Si quiere ejecutar la funci贸n callback cada vez que la visibilidad pase otro 25%, usted deber铆a especificar el array [0, 0.25, 0.5, 0.75, 1]. El valor por defecto es 0 (lo que significa que tan pronto como un p铆xel sea visible, la funci贸n callback ser谩 ejecutada). Un valor de 1.0 significa que el umbral no se considera pasado hasta que todos los pixels son visibles.

Determinando un elemento para ser observado

Una vez usted ha creado el observer, necesita darle un elemento target para observar:

var target = document.querySelector('#listItem');
observer.observe(target);

Cuando el elemento target encuentra un threshold especificado por el IntersectionObserver, la funci贸n callback es invocada. La funci贸n callback recibe una lista de objetos IntersectionObserverEntry y el observer:

var callback = function(entries, observer) { 
  entries.forEach(entry => {
    // Cada entry describe un cambio en la intersecci贸n para
    // un elemento observado
    //   entry.boundingClientRect
    //   entry.intersectionRatio
    //   entry.intersectionRect
    //   entry.isIntersecting
    //   entry.rootBounds
    //   entry.target
    //   entry.time
  });
};

Aseg煤rese de que su funci贸n callback se ejecute sobre el hilo principal. Deber铆a operar tan r谩pidamente como sea posible; si alguna cosa necesita tiempo extra para ser realizada, use Window.requestIdleCallback().

Tambi茅n, note que si especifica la opci贸n root, el elemento target debe ser un descendiente del elemento root.

el IntersectionObserver ya nos regresa una bandera 鈥渋sIntersecting鈥

time: 16506.95500000006
rootBounds: DOMRectReadOnly {x: 0, y: 0, width: 1149, height: 978, top: 0, 鈥
boundingClientRect: DOMRectReadOnly {x: 94.5, y: -389.125, width: 960, height: 540, top: -389.125, 鈥
intersectionRect: DOMRectReadOnly {x: 94.5, y: 0, width: 960, height: 150.875, top: 0, 鈥
isIntersecting: true
intersectionRatio: 0.2793981432914734
target: video.movie
isVisible: false

con la cual podemos hacer nuestro handleIntersection de la siguiente manera

handleIntersection(entries){
        const enty = entries[0]
        if(enty.isIntersecting){
            this.player.play()
        }
        else{
            this.player.pause()
        }
    }

Aqu铆 el c贸digo de los comentarios del video鈥 s贸lo para agregar m谩s items a la lista.

<h2>Comments</h2>
    <ul>
      <li>
        Lorem, ipsum dolor sit amet consectetur adipisicing elit. Saepe natus
        non officiis a repellendus molestias ipsum aspernatur, adipisci
        temporibus vel maiores omnis ad facere nihil asperiores. Aspernatur odit
        esse eos.
      </li>
      <li>
        Numquam eaque deleniti, debitis saepe vero, odit quidem ut dolor nemo,
        exercitationem commodi illo minus id ratione minima? Enim eum
        consequatur eveniet unde accusamus alias ipsam sed blanditiis dicta!
        Sequi.
      </li>
   </ul>

Recuerden que tambi茅n pueden usar Arrow Functions en vez de Funciones normales y as铆 no tienen que hacer el bind(this). Quedar铆an algo as铆 las funciones:

handleIntersection = entries => {
	...
}

Cuando tenemos el video en pausado y bajamos y posteriormente subimos, se reproduce autom谩ticamente aunque lo hayamos tenido en pausa.

Para fixear esto podr铆amos agregar una variable que se haga true cuando el video se salga de la pantalla SIEMPRE Y CUANDO nuestro video se haya estado reproduciendo, esta variable (que yo llam茅 pausedByScroll) se har铆a en el constructor para que no sea olvidada con cada iteraci贸n de la funci贸n handleIntersection(). Cuando se vuelva a subir, es decir, cuando isVisible sea true, se har谩 una verificaci贸n de que this.pausedByScroll sea TRUE (que el reproductor fue desactivado por el scroll y no manualmente), si pasa esta verificaci贸n lo reproducir谩 y si no, seguir谩 desactivado.

    constructor() {
        this.threshold = 0.25;
        this.handleIntersection = this.handleIntersection.bind(this)
        this.pausedByScroll = false;
    }
    handleIntersection(entries) {
        const entry = entries[0];
        const isVisible = entry.intersectionRatio >= this.threshold;
        if (isVisible) {
            if(this.pausedByScroll) {
                this.pausedByScroll = false;
                this.player.play();
            }
        } else {
            if(!this.player.media.paused) {
                this.pausedByScroll = true;
                this.player.pause();
            }
        }
        console.log(entry)
    }

No s茅 si habr谩 sido la mejor soluci贸n, pero fue la m谩s eficiente que se me ocurri贸, compartan otras soluciones y comparemos 馃槂

buena clase profe, para complementar, les dejo el video de Leonidas, es muy buen video sobre este tema.

https://www.youtube.com/watch?v=Mm9R1Z5B31s&t=761s

Hola! Hice la l贸gica un poco diferente e incorpor茅 la funci贸n get y set explicadas en las clases anteriores. Para saber si el elemento es visible utilizo la propiedad isIntersecting que viene con el IntersectionObserver.

Les comparto mi c贸digo:

class AutoPause {
  constructor() {
    this.threshold = 0.25
    this._player = {}
  }

  get player() {
    return this._player
  }

  set player(player) {
    this._player = player
  }

  run(player) {
    this.player = player
    this.handleInterseption = this.handleInterseption.bind(this)
    const observer = new IntersectionObserver(this.handleInterseption, {
      threshold: this.threshold
    })

    observer.observe(this.player.media)
  }

  handleInterseption(entries) {
    const entry = entries[0]
    const { play, pause } = this.player
    !entry.isIntersecting ? pause() : play()
  }
}

export default AutoPause

Buenas, me di cuenta en la clase que richard hizo una cosa que esta programaticamente bien. Y fue hacerle el bind al handler.

Esto lo pueden evitar de ES6 en adelante si en vez de llamar funciones convencionales llaman Arrow Functions.

Es decir, en vez de esto

handler(){
	//your code
}

Hacen esto

handler = () => {
	//your code
}

Esto pasa porque las Arrow Function son funciones sin contexto es decir todo lo que suceda dentro de ellas tienen el contexto del padre. Por lo que, por definicion toman el contexto de la clase directamente. Hacen como un AutoBind hacia la clase y automaticamente toman el contexto de su padre.

Espero les sirva 馃槂

Tambi茅n funciona con la propiedad isIntersecting del entry, un booleano que indica si se cumplen las condiciones de los options (el threshold definido a .25)

entry.isIntersecting ? this.player.play() : this.player.pause();

Un consejo: Vean el video, lean la documentaci贸n de Intersection Observer, y despu茅s vuelvan a ver el video. Entiendes a la perfecci贸n!

Uhh que genial! Esto facilita muchas cosas, y dato curioso, aqu铆 si usamos las clases de ES2015 jaja

Mis apuntes, genial este feacture!! 馃槃

/*
  Intersection Observer sirve observar elementos y si cruzan un umbral(threshold)
  que se define dentro de un contenedor, en este caso window, IntersectionObserver nos lo notifica
  y con eso podemos hacer algo.
*/

function AutoPause(){
  this.threshold = 0.25;
  this.handlerIntersection = this.handlerIntersection.bind(this);
}

AutoPause.prototype.run = function(player){
  this.player = player;
  /*
    IntersectionObserver recibe dos parametros,

    handler --> Funcion que recibe el "aviso" de que hubo una interseccion en el elemento que se
    observa
    config --> objeto de configuracion
  */
  const observer = new IntersectionObserver(this.handlerIntersection, {
    /* Define un umbral, es decir que porcentaje de un elemento dentro de un contenedor tiene que interceptar
      para avisar
    */
    threshold: this.threshold
  });
  observer.observe(this.player.media);
}

/*
  Cuando IntersectionObserver llame al handler, le pasa una lista de entries, los cuales son todos los objetos
  que se est谩n observando, un Array.
*/
AutoPause.prototype.handlerIntersection = function(entries){
  const entry = entries[0];
  const isVisible = entry.intersectionRatio >= this.threshold;
  if(isVisible){
    this.player.play();
  } else {
    this.player.pause();
  }
}

export default AutoPause;```

me gusto la clase

yo lo hice as铆, el handler tambi茅n tiene una propiedad llamada isIntersecting que nos avisa pues si est谩 intersectando :b

es un booleano, entonces aqu铆 pongo que cuando ese booleano sea false lo pause

import MediaPlayer from "../MediaPlayer.js"
let newPlayer

class AutoPause{
    run(player){
        newPlayer= player
        console.log(this.player)
        const observer= new IntersectionObserver(this.handlerIntersection, {
            threshold: .25
        } )
        observer.observe(player.media)
        newPlayer=player
    }
    //entries es todos los objetos que estamos observando
    handlerIntersection(entries){
        console.log(newPlayer)
        const entry= entries[0]
        //como solo estamos observando un objeto le decimos que solo el primero
        console.log(entry)
        if(entry.isIntersecting){
            newPlayer.media.play()
        }else{
            newPlayer.media.pause()
        }
    }
}
export default AutoPause```

encontr茅 otra forma distinta sin recurrir al threshold, cuando hacemos el log a la const entry, notamos que dentro tiene algo llamado isIntersecting, lo unico que hay que hacer es validar el valor de isIntersecting en el if, y cuando sea falso que pare el video, cuando sea verdad, lo reproduzca
aqu铆 una imagen para que lo entiendan mejor
(

Yo por ejemplo us茅 el objeto entry en su propiedad isIntersecting en lugar de hacer la comparaci贸n con el threshold.

...
  handleIntersection(entries) {
    const entry = entries[0];

    if (entry.isIntersecting) {
      this.player.play();
    } else {
      this.player.pause();
    }
  }
...

Usando Arrow Functions es posible ligar el contexto 鈥渢his鈥 y no es necesario el bind

class AutoPause {
  constructor() {
    this.threshold = 0.25;
    //this.handleIntersection = this.handleIntersection.bind(this);
  }

  run = (player) => {
    this.player = player;

    const observer = new IntersectionObserver(this.handleIntersection, {
      threshold: this.threshold,
    });

    observer.observe(this.player.media);
  }

  handleIntersection = (entries) => {
    const entry = entries[0];

    const isVisible = entry.intersectionRatio >= this.threshold;

    if (isVisible) {
      this.player.play();
    } else {
      this.player.pause();
    }
  }
}```

Aqu铆 otro ejemplo es por parte de Leonidas Esteban Video de leo

Veo a IntersectionObserver como la vecina chismosa que siempre esta pendiente de cuando sales y cuando llegas xD

Memocione y le meti algo de css jasjas

Aqu铆 otra opci贸n que usa otra propiedad del objeto entregado por el observer

<  
handlerIntersection(entries){
    const entry = entries[0];
    entry.isIntersecting
    ?this.player.play()
    :this.player.pause()
  }
>

隆Hola a todos!
Tengo un problema con mi c贸digo. Me parece que tengo todo igual, solo cambi茅 el estilo de la clase a puro Javascript (me parece que el concepto de clases es de Typescript y lo quise hacer as铆, para ver si se solucionaba el error):

function AutoPause(){}

AutoPause.prototype.run = function(player){
    //debugger
    const observer = new IntersectionObserver(this.handleIntersection, {
        threshold: 0.25
    })

    observer.observe(player.media)
    
}

AutoPause.prototype.handleIntersection = function(entries){
    const entry = entries[0]
    console.log(entry)
}

Y me aparece este error:

隆Gracias de antemano!

脕nimos! Ya vas por la mitad!

Gracias!!, muy interesante

Que genial, me gust贸 mucho

Wowo, que 煤til:

[La API Observador de Intersecci贸n provee una v铆a as铆ncrona para observar cambios en la intersecci贸n de un elemento con un elemento ancestro o con el viewport del documento de nivel superior.

Hist贸ricamente, detectar la visibilidad de un elemento, o la visibilidad relativa de dos elementos, uno respecto del otro, ha sido una tarea dif铆cil para la cual las soluciones no han sido muy fiables y propensas a causar que el navegador y los sitios a los que el usuario accede lleguen a ser lentos. A medida que la web ha madurado, la necesidad para este tipo de informaci贸n ha ido en aumento. La informaci贸n sobre intersecci贸n es necesaria por muchas razones, tales como:

Lazy-loading de im谩genes u otro contenido a medida que la p谩gina se desplaza.
Implementaci贸n de 鈥渟croll infinito鈥 de sitios web, donde m谩s y m谩s contenido se carga y muestra a medida que usted hace scroll, de forma que el usuario no tiene que pasar p谩ginas.
Informes de visualizaciones de anuncios para calcular ingresos por publicidad.
Decidir si deben realizarse tareas o procesos de animaci贸n basados en si el usuario ver谩 o no el resultado.](https://developer.mozilla.org/es/docs/Web/API/Intersection_Observer_API)

Supongo que es asi como se crean esas paginas dinamicas que cuando haces scroll down te van apareciendo animaciones.

muy buena Clase a seguir aprendiendo

Simplemente hermoso

Esto no lo conocia siempre lo generaba de manera manual

Tambien se puede usar entry.isIntersecting para hacer pausar o continuar el video

handleIntersection(entries) {
        const entry = entries[0]

        if (entry.isIntersecting) {
            this.player.play()
        } else {
            this.player.pause()
        }
    }

脡sta clase est谩 muy buena, pero tarde en comprender la parte del bind, aunque aqu铆 est谩 mi explicaci贸n:

//Esta l铆nea se agrego porque this.player.pause() no pod铆a acceder al m茅todo de undefined
//Esto sucede porque handleIntersection es llamada desde intersectionObserver, la cual no tiene al player en su instancia
//Est谩 l铆nea corrige el error ya que establece permanentemente el this, a la instancia del objeto, a handleIntersection
//Ahora que cada que se referencie a this desde la funci贸n handleIntersection, se estara haciendo referencia a la instancia del player.
this.handleIntersection = this.handleIntersection.bind(this);```


Si estas leyendo esto es porque vas por la mitad. Bravo!.

脕nimo, que si se puede.

aqui podran tener mas infromacion certera sobre intersectionObserver y sus ante pasados (informacion legitima y oficial)
https://developer.mozilla.org/es/docs/Web/API/Intersection_Observer_API

Asi como cuando sientes que cada video que ves te deja boquiabierto y con ganas de hacer de todo en JavaScript, pues asi me siento despues de 7 anhos JavaScript y sin saber estas mejoras increibles!

En mi caso no me funciono, entry.IntersectionRatio, por lo que lo hice asi y me funciono.

handleTntersection(entries) {
        const entry = entries[0];
        const isVisible = entry.isIntersecting;

        if (isVisible){
            console.log("job")
            this.player.play();
        }
        else {
            console.log("boj")
            this.player.pause();
        }

les comparto mi c贸digo. En vez de usar this.player utilizo una propiedad que tiene el IntersectionObserver.target. As铆 por defecto las funciones apuntan al mismo objeto que retorna.
Adicionalmente utilizo entry.isIntersecting para no tener que validar n煤meros si el objeto es visible o no (de acuerdo a la configuraci贸n que se le d茅).

class AutoPuse{
    constructor(){
        this.threshold = 0.25
    }

    run(player){
        this.player = player;
        const observer = new IntersectionObserver(this.handlerIntersection, 
            {threshold: this.threshold})
        observer.observe(this.player.media)
    }
    handlerIntersection(entries){
        const entry = entries[0];
        console.log(entry);
        if (entry.isIntersecting === false) {
            entry.target.pause();
        }else{
            entry.target.play();
        }
    }
}

la verdad yo no pude hacerlo como en el video, pero encontr茅 una forma de hacerlo que a i parecer es mucha mas simple y f谩cil, en vez de usar la propiedad intersectionRatio use la propiedad isIntersecting que retorna un valor booleano si el elemento ha sido interceptado, les comparto mi c贸digo 馃槂

<class AutoPause {
  constructor() {}
  run(player) {
    let observer = new IntersectionObserver(this.handlerIntersection);
    observer.observe(player.media)
  }
  handlerIntersection(entries) {
    let entry = entries[0];
    console.log(entry);
    if (!entry.isIntersecting) {
      player.pause();
    } else {
      player.play();
    }
  }
}> 

驴Qu茅 es IntersectionObserver?
Sirve para observar elementos (asincr贸nicamente) y si cruzan un umbral que nosotros definimos nos lo va a notificar para tomar acci贸n.

Viewport
Parte del documento que actualmente se ve en el navegador web.

Que tal campeon, buen dia鈥

Increible鈥 Vamos bien, por ahora.

Hola a mi me daba un error que hasta la segunda accion cambia a play o pause. Aca tienen mi solucion.

handleIntersection(entries) {
   const entry = entries[0];

   const isVisible = entry.intersectionRatio >= this.threshold;
   
   if (!!isVisible) {
    this.player.media.play();
    } else {
    this.player.media.pause();
  }
 }

Yo use entry.isIntersecting para saber si el video entraba o salia 馃槂

A este tipo no se le entiende, con razon lo quitaron de profesor es malisimo explicando, no lo recomiendo para aprender, en serio hace las cosas y uno se queda igual, repito varias partes del video y no entiendo nada

Definitivamente muy mal profesor, se salta detalles tan importantes en contextualizar lo que esta ense帽ando, en mi casi ir a la documentaci贸n y ver el video me hizo ver que es p茅simo profesor.

isIntersecting es un atributo de entry que nos dice si est谩 dentro del margen o no.

Escribiendo el handleIntersection de una manera mas fancy

handleIntersection(entries) {
        const entry = entries[0]

        const isVisible = entry.intersectionRatio >= this.threshold
    
        isVisible ? 
        this.player.play() : 
        this.player.pause()
    }

煤til clase!!!

Sirve para observar elementos y si cruzan un umbral que nosotros definimos nos lo va a notificar para tomar acci贸n.

El umbral se define por el porcentaje que tiene intersecci贸n con el viewport, con la parte visible de nuestra p谩gina.

IntersectionObserver se pone a observar un elemento y mira cu谩l es su posici贸n. Nosotros le pasaremos un objeto de configuraci贸n donde definiremos unas marcas.

  • Ej: Si el objeto est谩 tiene una intersecci贸n de 25% con respecto a la pantalla dejanos saber.

Recibe un handler, una funci贸n que va a recibir el anuncio de la intersecci贸n, es decir, se ejecutar谩 cuando se den las circunstaciones definidas en el objeto de configuraci贸n.

const observer = new IntersectionObserver(this.handlerIntersection, {
    threshold: this.threshold,
});

Ejemplo de un IntersectionObserver:

let options = {
  root: document.querySelector('#scrollArea'),
  rootMargin: '0px',
  threshold: 1.0
}

let observer = new IntersectionObserver(callback, options);

Definimos el observer y le pasamos como par谩metro un callback que es el handler. Y un objeto de configuraci贸n llamado options donde definimos las opciones del IntersectionObserver (root, rootMargin, threshold).

Root: El聽elemento que es usado como viewport para comprobar la visibilidad de elemento聽target. Debe ser ancestro de target. Por defecto es el viewport del navegador si no se especifica o si es null.

rootMargin: Margen alrededor del elemeto聽root.

threshold: Es un n煤mero o un array de n煤meros que indican a que porcentaje de visibilidad del elemento target, la funci贸n callback del observer deber铆a ser ejecutada. Si usted quiere que se detecte cuando la visibilidad pasa la marca del 50%, deber铆a usar un valor de 0.5.

var target = document.querySelector('#listItem');
observer.observe(target);

Cuando el elemento target encuentra un threshold especificado聽por el IntersectionObserver, la funci贸n callback es invocada. La funci贸n callback recibe una lista de objetos IntersectionObserverEntry y el聽observer:

var callback = function(entries, observer) {
  entries.forEach(entry => {
    // Cada entry describe un cambio en la intersecci贸n para
    // un elemento observado
    //   entry.boundingClientRect
    //   entry.intersectionRatio
    //   entry.intersectionRect
    //   entry.isIntersecting
    //   entry.rootBounds
    //   entry.target
    //   entry.time
  });
};

https://developer.mozilla.org/es/docs/Web/API/Intersection_Observer_API

Yo utilice el atributo 鈥榠sIntersecting鈥 el cual devuelve un valor boolean directamente dependiendo del Threshold que asignes, basicamente el codigo funciona de la misma manera:

handlerIntersection(entries) {
        const entry = entries[0];
        console.log(entry);

        if(!entry.isIntersecting) {
            this.player.pause() 
        } else {
            this.player.play()
        }
    }

Inicia codigo IntersectionObserver.

Muy buena clase !!!

S煤per interesante para hacer lazy loading 馃殌

por aca coloco un video de Leonidas Esteban en donde explica el IntersectionObserver con un ejemplo practico

https://www.youtube.com/watch?v=Mm9R1Z5B31s

Excelente profe. Es una chingoner铆a!!

Es obligatorio tener todos los conceptos de las clases claros? Me parece algo abrumador

muy interesante esta api de intersectionObserver

AAAAA, vengo arrastrando un error con el AutoPlay, que ahora con el AutoPause empeor贸. El AutoPlay, cuando no est谩 la l铆nea de c贸digo

  else if(!isVisile) {
      this.player.pause()
    }```
funciona, pero si est谩 me tira este error.
Uncaught (in promise) DOMException: The play() request was interrupted by a call to pause().
Estoy rendido

Tambi茅n se pueden usar funciones flecha para mantener el m茅todo con el bind a la clase AutoPause:

class AutoPause {
    constructor() {
        this.threshold = 0.25;
    }

    run(player) {
        this.player = player;

        const observer = new IntersectionObserver(this.handleIntersection, {
            threshold: this.threshold
        });
        observer.observe(player.media);
    }

    handleIntersection = (entries) => {
        const entry = entries[0];

        const isVisible = entry.intersectionRatio >= this.threshold;

        if (isVisible) {
            this.player.play();
        } else {
            this.player.pause();
        }
    }
}

export default AutoPause;

Recibo el siguiente error en consola: Uncaught TypeError: this.player.pause is not a function
at AutoPause.handleIntersection (AutoPause.js:39)

<handleIntersection(entries)//entries son los objetos que estamos observando
    {
        const entry = entries[0];//solo observamos uno en la lista
        

        const isVisible =  entry.intersectionRatio >= this.threshold

        if(isVisible)//si esta visible
        {

            this.player.play()//le damos play
        }
        else
        {
            this.player.pause()//si no, lo detenemos
        }

    }>

alguien podria ayudarme

Tambien hay otra forma de hacer lo mismo:

handleIntersection(entries) {
    const entry = entries[0]
    
    if (entry.isIntersecting) {
      this.player.play()
    } else {
      this.player.pause()
    }
  }

Me gust贸 mucho esta clase, parece que ser谩 de mucha utilidad el IntersectionObserver.

otra soluci贸n

    handlerIntersection(entries){
        const entry = entries[0]
        !entry.isIntersecting?entry.target.pause():entry.target.play()
    }

si el elemento no esta dentro del umbral definido la propiedad isIntersecting sera falsa por ende procedemos a pausar el video. de lo contrario le daremos play.

Uffffff que buena funcionalidad de javascript!

Cool. Se le puede sacar mucho provecho. Ahora si entiendo como funciona el autoplay y pause de los videos de facebook.

hola tengo problemas con mi trabajo y me arroja los siguientes errores

AutoPause.js:13 Uncaught ReferenceError: observer is not defined
at AutoPause.run (AutoPause.js:13)
at MediaPlayer.js:22
at Array.forEach (<anonymous>)
at MediaPlayer._initPlugins (MediaPlayer.js:21)
at new MediaPlayer (MediaPlayer.js:5)
at index.js:6

bind es una gran utilidad!!

es bueno verlo dos veces y acompa帽ado de la lectura sugerida.
馃槂

brutal!!

Use otra propiedad para verificar si el MediaPlayer esta siendo o no intersectado.

    handlerIntersection([media]){
         if (media.isIntersecting){
            this.player.play()
         }else{             
            this.player.pause()
         }
    }

esto me encanta.

Muy buena esta Clase. Excelente

Sirve para observar elementos y si cruzan un umbral que nosotros definimos nos lo va a notificar para tomar acci贸n.

El umbral se define por el porcentaje que tiene intersecci贸n con el viewport, con la parte visible de nuestra p谩gina.

Excelente clase!!!

Una de mis funcionalidades favoritas

Me gusta ver las cosas simples, entonces aqu铆 les dejo un ejemplo m谩s sencillo.

Ingresas a about:blank en chrome y agregas estos estilos

div {
    height: 500px;
    width: 500px;
    background: red;
    margin: 5px;
}
div:first-child {
    background: blue;
}

Seguido a esto, en la consola ejecutas este ejemplo del intersection observer

const body = document.querySelector('body')
for (let i = 0; i < 4; i++) {
    let div = document.createElement('div')
    body.appendChild(div)
}

function handler(entry) {
    if (entry[0].intersectionRatio >= this.threshold) {
        console.log('it is visible')
    } else {
        console.log('it is NOT visible')
    }
}

const config = {
    threshold: 0.25
}

handler = handler.bind(config)

const observer = new IntersectionObserver(handler, config)

let firstDiv = document.querySelector('div')
observer.observe(firstDiv, handler)

Mueve el scroll y observa la magia 馃槂

seguimos avanzando鈥

Muy buena esta funcionalidad!

Me gustar铆a compartirles mis apuntes de esta clase, los pueden encontrar en este link, es un PDF y espero que les sirva!!

Aqu铆 mi c贸digo con Set y Get

class AutoPause {
    constructor() {
        this.threshold = 0.2
        this.handleIntersection = this.handleIntersection.bind(this)
    }

    run(player){
        this.player = player

        const intersection = new IntersectionObserver(this.handleIntersection, { threshold: this.threshold, })

        intersection.observe(this.player.media);
    }
    
    handleIntersection(entries) {
        const entry = entries[0]

        const isVisible = entry.intersectionRatio >= this.threshold

        if (isVisible){
            console.log('es visible')
           this.player.toggle = true
        }else{
            this.player.toggle = false
        }

        console.log(entry)
    }
}
export default AutoPause
function MediaPlayer(config) {
    this.media = config.el
    this.plugins = config.plugins || []; 

    this._initPlugins();
  };

  MediaPlayer.prototype._initPlugins = function() {
    const player = {
        media: this.media,

        get muted() {
            return this.media.muted;
        },

        set mute(value){
            this.media.muted = value
        },

        get toggle() {
            return this.media.play();
        },

        set toggle(value){
            value ? 
                this.media.play() : this.media.pause()
        }
    }

    this.plugins.forEach(plugin => {
        plugin.run(player);
    })
  }
  
  MediaPlayer.prototype.toggle = function() {
    this.media.paused ?
      this.media.play() : this.media.pause()
  }

  MediaPlayer.prototype.muteToggle = function() {
      this.media.muted ?
        this.media.muted = false : this.media.muted = true;
  }



export default MediaPlayer
handleIntersection(entries) {
    const entry = entries[0]
    entry.intersectionRatio >= this.threshold ? this.player.play() : this.player.pause()
  }

Super muy bueno

Muy bueno para hacer lazy loading de partes de la p谩gina.

隆Excelente clase!

Qu茅 geniaaal. 馃槃

Les comento que tenia un problema, ya que el intersectionRatio nunca daba por encima del treshold, por lo que el video se pausaba, pero no se reanudaba(nunca ingresaba al true del if).

Lo resolvi como sugirio Agustin Zamar en los comentarios, usando entry.isIntersecting.

export default class AutoPause {
    constructor() {
        this.treshold = 0.25;
        this.handleIntersection = this.handleIntersection.bind(this);
    }
        

    run(player) {
        //guardamos el player en una instancia de la clase, asi podemos inicalizarlo o pausarlo
        this.player = player;
        //creamos un nuevo Intersection Observer
        const observer = new IntersectionObserver(this.handleIntersection, {treshold: this.treshold,});
        observer.observe(this.player.media);
    }
    
    handleIntersection(entries) {
    const entry = entries[0];
    if (entry.isIntersecting) {
        this.player.play();
    } else {
        this.player.pause();
    }
    }


}```

Cuando Richard dijo 鈥淧odemos!鈥 yo dije 鈥淣o mames awebo.鈥

class AutoPause {
    constructor() {
        this.threshold = 0.25;
        this.handleIntersection = this.handleIntersection.bind(this);
    }

    run(player) {
        this.player = player;
        const observer = new IntersectionObserver(this.handleIntersection, {
            threshold: 0.25
        })

        observer.observe(this.player.media)
    }

    handleIntersection(entries) {
        const entry = entries[0];

        const isVisible = entry.intersectionRatio >= this.threshold;

        if (isVisible) {
            this.player.play();
        } else {
            this.player.pause();
        }
        
        console.log(entry);
    }
}

export default AutoPause;

Genial muy util estas herramientas

Estos son los usos m谩s comunes del IntersectionObserver:

  • Lazy-loading de im谩genes u otro contenido a medida que la p谩gina se desplaza.

  • Implementaci贸n de 鈥渟croll infinito鈥 de sitios web, donde m谩s y m谩s contenido se carga y muestra a medida que usted hace scroll, de forma que el usuario no tiene que pasar p谩ginas.

  • Informes de visualizaciones de anuncios para calcular ingresos por publicidad.

  • Decidir si deben realizarse tareas o procesos de animaci贸n basados en si el usuario ver谩 o no el resultado.

muy util.

genial 馃槂

隆Qu茅 interesante!

Super bueno!

馃槻 Excelente herramienta, aunque por lo que vi tambi茅n pod铆amos usar directamente el valor que nos daba isIntersecting, no?

Tengo una duda, puede ser que Intersection Observer funcione mal con objetos que est谩n en hidden o en display none? me pasa que tengo un intersecti贸n observer en una caja para hacer un slider, y la verdad, termin茅 optando por duplicar el pedazo en html para mobile, antes de que me pudiera llegar a reconocer a los objetos

Maravilloso. Ya lo visualizo para hacer navegaciones din谩micas dentro de un sitio web, haciendo que cambien los estilos del sitio dependiendo de que se muestra en pantalla o para hacer lazy downloads de archivos y mejorar el performance

Mi version de este plugin: en este caso use 0.5 en threshold y en la condicion use target del intersectionObserver para manipular el video

class AutoPause {
    run(player){
        const observer = new IntersectionObserver(this.handler,{
            threshold:0.5
        })
        observer.observe(player.media)
    }
    handler(entries){
        const entry = entries[0]
        console.log(entry)
        if(entry.isIntersecting===true){
            entry.target.play()
        }
        if(entry.isIntersecting===false){
            entry.target.pause()
        }
    }
}

export default AutoPause