Considere marcar o manipulador de eventos como 'passivo' para tornar a página mais responsiva

217

Estou usando o martelo para arrastar e está ficando irregular ao carregar outras coisas, como esta mensagem de aviso está me dizendo.

A manipulação do evento de entrada 'touchstart' foi atrasada por X ms devido ao segmento principal estar ocupado. Considere marcar o manipulador de eventos como 'passivo' para tornar a página mais responsiva.

Então eu tentei adicionar 'passivo' ao ouvinte assim

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

mas ainda estou recebendo esse aviso.

Matt
fonte

Respostas:

264

Para aqueles que recebem esse aviso pela primeira vez, isso se deve a um recurso de ponta chamado Passive Event Listeners que foi implementado nos navegadores recentemente (verão de 2016). Em https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md :

Os ouvintes de eventos passivos são um novo recurso na especificação do DOM que permite que os desenvolvedores optem por melhorar o desempenho da rolagem, eliminando a necessidade de rolagem para bloquear os ouvintes de eventos por toque e roda. Os desenvolvedores podem anotar ouvintes sensíveis ao toque e alternar com {passive: true} para indicar que eles nunca chamarão preventDefault. Esse recurso foi lançado no Chrome 51, Firefox 49 e desembarcou no WebKit. Para uma explicação oficial completa, leia mais aqui.

Veja também: O que são ouvintes de eventos passivos?

Pode ser necessário aguardar a biblioteca .js para implementar o suporte.

Se você estiver manipulando eventos indiretamente por meio de uma biblioteca JavaScript, poderá estar à mercê do suporte dessa biblioteca específica ao recurso. Em dezembro de 2019, não parece que nenhuma das principais bibliotecas tenha implementado suporte. Alguns exemplos:

Anson Kao
fonte
16
e as bibliotecas iônicas?
abhit
10
Estou ligando preventDefault()- é possível suprimir esse aviso?
Maja
12
A versão 3 da API JavaScript do Google Maps também gera esses avisos. O problema está sendo rastreado em issuetracker.google.com/issues/63211698 . (É uma ironia, considerando que o Google Chrome está alertando sobre as violações que o Google Maps JavaScript API gera.)
Jochem Schulenklopper
6
para suprimir esse aviso, você pode `addEventListener ('touchstart', this.callPassedFuntion, {passive: false})` #
Shlomi Schwartz
8

Isso oculta a mensagem de aviso:

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
fonte
5
O objetivo não seria parar o evento real? Eu não gostaria de ocultar a mensagem até que eu tenha resolvido o problema.
yardpenalty.com 27/02/19
1
Eu acho que é um problema de biblioteca jquery. Eu acho que os desenvolvedores devem corrigi-lo. Mas se você conseguir, deixe-me saber como fazê-lo, por favor. Muito obrigado.
Iván Rodríguez
Com certeza Ivan! Sim, ele é. Ei, agora estou curioso ... Estou usando o plugin d3 e estou recebendo 2300 violações. Talvez o seu código ajude! Vou mantê-lo informado!
yardpenalty.com 27/02/19
@ yardpenalty.com, não, parar o evento não é o objetivo! O aviso indica que você colocou seu ouvinte sem especificar se ele pode ou não impedir o comportamento padrão no evento. Se você tiver casos em que deseja ligar preventDefault(), especifique passive: false. Caso contrário, especifique passive: true. Você só recebe o aviso se não especificar também. Se você especificar passive: truee preventDefault()for chamado, isso resultará em um erro e o padrão não será impedido. A especificação passivenão é um hack aqui. É a solução . É o que o aviso pede!
tao
@ tao obrigado pelo comentário. Já faz alguns anos, mas definitivamente lembrarei da solução no futuro!
yardpenalty.com 30/04
1

Também encontre isso no plug-in suspenso select2 no Laravel. Alterando o valor conforme sugerido por Alfred Wallace de

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

para

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

resolve o problema. Por que ele tem voto negativo, eu não sei, mas funciona para mim.

Jun Salen
fonte
0

Para aqueles que enfrentam problemas herdados, encontre a linha que lança o erro e adicione {passive: true}- por exemplo:

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

torna-se

this.element.addEventListener(t, e, { passive: true} )
Alfred Wallace
fonte
-1

Encontrei uma solução que funciona no jQuery 3.4.1 slim

Depois de desminificar, adicione {passive: true}à função addEventListener na linha 1567 da seguinte forma:

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

Nada quebra e as auditorias de farol não reclamam dos ouvintes.

Mark Lancaster
fonte
1
nunca mude o código fonte de uma biblioteca; você deve substituí-lo.
Raptor