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.

Mate
fuente

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:

Anson Kao
fuente
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 });
    }
  }
};
Iván Rodríguez
fuente
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.

Jun Salen
fuente
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} )
Alfred Wallace
fuente
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') });
    }
};
AndreyP
fuente
-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.

Mark Lancaster
fuente
1
nunca cambie el código fuente de una biblioteca; deberías anularlo en su lugar.
Raptor