Considere marcar el controlador de eventos como 'pasivo' para que la página sea más receptiva


217

Estoy usando un martillo para arrastrar y se está entrecortando al cargar otras cosas, como me dice este mensaje de advertencia.

El manejo del evento de entrada 'touchstart' se retrasó por X ms debido a que el subproceso principal está ocupado. Considere marcar el controlador de eventos como 'pasivo' para que la página sea más receptiva.

Así que intenté agregar 'pasivo' al oyente así

Hammer(element[0]).on("touchstart", function(ev) {
  // stuff
}, {
  passive: true
});

pero sigo recibiendo esta advertencia.

Respuestas:


264

Para aquellos que reciben esta advertencia por primera vez, se debe a una característica innovadora llamada Passive Event Listeners que se implementó en los navegadores recientemente (verano de 2016). Desde https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md :

Los oyentes de eventos pasivos son una nueva característica en la especificación DOM que permite a los desarrolladores optar por un mejor rendimiento de desplazamiento al eliminar la necesidad de desplazarse para bloquear los oyentes de eventos táctiles y de rueda. Los desarrolladores pueden anotar oyentes táctiles y de rueda con {pasivo: verdadero} para indicar que nunca invocarán preventDefault. Esta característica se envió en Chrome 51, Firefox 49 y aterrizó en WebKit. Para una explicación oficial completa, lea más aquí.

Ver también: ¿Qué son los oyentes de eventos pasivos?

Puede que tenga que esperar a que su biblioteca .js implemente el soporte.

Si está manejando eventos indirectamente a través de una biblioteca de JavaScript, puede estar a merced del soporte de esa biblioteca en particular para la función. A partir de diciembre de 2019, no parece que ninguna de las principales bibliotecas haya implementado el soporte. Algunos ejemplos:


16
¿Qué pasa con las bibliotecas iónicas?
— abhit

10
Estoy llamando preventDefault(). ¿Es posible suprimir esta advertencia?
— maja


12
La versión 3 del API de JavaScript de Google Maps también genera estas advertencias. El problema se está rastreando en issuetracker.google.com/issues/63211698 . (Es irónico, considerando que Google Chrome advierte sobre las violaciones que genera la API de JavaScript de Google Maps).
— Jochem Schulenklopper

66
para suprimir esta advertencia puede `addEventListener ('touchstart', this.callPassedFuntion, {pasivo: falso})`
— Shlomi Schwartz

9

Esto oculta el mensaje de advertencia:

jQuery.event.special.touchstart = 
{
  setup: function( _, ns, handle )
  {
    if ( ns.includes("noPreventDefault") ) 
    {
      this.addEventListener("touchstart", handle, { passive: false });
    } 
    else 
    {
      this.addEventListener("touchstart", handle, { passive: true });
    }
  }
};

55
¿No sería el objetivo ser detener el evento real? No quisiera ocultar el mensaje hasta que haya solucionado el problema.
— yardpenalty.com

1
Creo que es un problema de la biblioteca jquery. Creo que los desarrolladores deberán solucionarlo. Pero si lo consigue, dígame cómo hacerlo, por favor. Muchas gracias.
— Iván Rodríguez

¡Seguro Ivan! Sí lo es. Hola, ahora tengo curiosidad ... Estoy usando el plugin d3 y obtengo unas 2300 violaciones. ¡Quizás tu código te ayude! ¡Te mantendré informado!
— yardpenalty.com

@ yardpenalty.com, no, ¡detener el evento no es el objetivo! La advertencia indica que ha colocado su escucha sin especificar si puede o no evitar el comportamiento predeterminado en el evento. Si tiene casos en los que desea llamar preventDefault(), debe especificar passive: false. Si no, especifique passive: true. Solo obtienes la advertencia si no especificas tampoco. Si especifica passive: truey preventDefault()recibe una llamada, se produce un error y no se evita el valor predeterminado. Especificar passiveno es un truco aquí. Es la solucion . ¡Es lo que pide la advertencia!
— tao

@tao gracias por tu comentario. Han pasado algunos años, pero definitivamente recordaré la solución en el futuro.
— yardpenalty.com

1

También encuentre esto en el complemento desplegable select2 en Laravel. Cambiar el valor sugerido por Alfred Wallace de

this.element.addEventListener(t, e, !1)

a

this.element.addEventListener(t, e, { passive: true} )

resuelve el problema No sé por qué tiene un voto negativo, pero me funciona.


0

Para aquellos atrapados en problemas heredados, busque la línea que arroja el error y agregue {passive: true}, por ejemplo:

this.element.addEventListener(t, e, !1)

se convierte

this.element.addEventListener(t, e, { passive: true} )

0

Para jquery-ui-dragable con jquery-ui-touch-punch lo arreglé de manera similar a Iván Rodríguez, pero con una anulación de evento más para touchmove:

jQuery.event.special.touchstart = {
    setup: function( _, ns, handle ) {
        this.addEventListener('touchstart', handle, { passive: !ns.includes('noPreventDefault') });
    }
};
jQuery.event.special.touchmove = {
    setup: function( _, ns, handle ) {
        this.addEventListener('touchmove', handle, { passive: !ns.includes('noPreventDefault') });
    }
};

-1

Encontré una solución que funciona en jQuery 3.4.1 slim

Después de desminificar, agregue {passive: true}a la función addEventListener en la línea 1567 de la siguiente manera:

t.addEventListener(p, a, {passive: true}))

Nada se rompe y las auditorías de los faros no se quejan de los oyentes.


1
nunca cambie el código fuente de una biblioteca; deberías anularlo en su lugar.
— Raptor
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.