Envisagez de marquer le gestionnaire d'événements comme «passif» pour rendre la page plus réactive

217

J'utilise un marteau pour faire glisser et cela devient saccadé lors du chargement d'autres choses, comme ce message d'avertissement me le dit.

La gestion de l'événement d'entrée «touchstart» a été retardée de X ms car le thread principal est occupé. Pensez à marquer le gestionnaire d'événements comme «passif» pour rendre la page plus réactive.

J'ai donc essayé d'ajouter "passif" à l'auditeur comme ça

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

mais je reçois toujours cet avertissement.

Mat
la source

Réponses:

266

Pour ceux qui reçoivent cet avertissement pour la première fois, cela est dû à une fonctionnalité de pointe appelée écouteurs d'événements passifs qui a été implémentée dans les navigateurs assez récemment (été 2016). Depuis https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md :

Les écouteurs d'événements passifs sont une nouvelle fonctionnalité de la spécification DOM qui permet aux développeurs de choisir de meilleures performances de défilement en éliminant la nécessité de faire défiler pour bloquer les écouteurs d'événements tactiles et mobiles. Les développeurs peuvent annoter les écouteurs tactiles et à molette avec {passive: true} pour indiquer qu'ils n'invoqueront jamais preventDefault. Cette fonctionnalité est livrée dans Chrome 51, Firefox 49 et a atterri dans WebKit. Pour une explication officielle complète, lisez plus ici.

Voir aussi: Que sont les écouteurs d'événements passifs?

Vous devrez peut-être attendre que votre bibliothèque .js implémente le support.

Si vous gérez des événements indirectement via une bibliothèque JavaScript, vous pouvez être à la merci du support de cette bibliothèque particulière pour la fonctionnalité. En décembre 2019, il ne semble pas que les principales bibliothèques aient implémenté le support. Quelques exemples:

Anson Kao
la source
16
qu'en est-il des bibliothèques ioniques?
abhit
10
J'appelle preventDefault()- Est-il possible de supprimer cet avertissement?
maja
12
L'API JavaScript de Google Maps version 3 génère également ces avertissements. Le problème est suivi sur issuetracker.google.com/issues/63211698 . (Un peu ironique, étant donné que Google Chrome met en garde contre les violations générées par l'API JavaScript de Google Maps.)
Jochem Schulenklopper
6
pour supprimer cet avertissement, vous pouvez `addEventListener ('touchstart', this.callPassedFuntion, {passive: false})`
Shlomi Schwartz
9

Cela masque le message d'avertissement:

jQuery.event.special.touchstart = {
  setup: function( _, ns, handle ) {
      this.addEventListener("touchstart", handle, { passive: !ns.includes("noPreventDefault") });
  }
};
Iván Rodríguez
la source
6
Le but n'est-il pas d'arrêter l'événement? Je ne voudrais pas cacher le message avant d'avoir résolu le problème.
yardpenalty.com
1
Je pense que c'est un problème de bibliothèque jquery. Je pense que les développeurs devront le réparer. Mais si vous l'obtenez, faites-le-moi savoir s'il vous plaît. Merci beaucoup.
Iván Rodríguez
Bien sûr, Ivan! Oui, ça l'est. Hé, maintenant je suis curieux ... J'utilise le plugin d3 et je reçois comme 2300 violations. Peut-être que votre code vous aidera! Je vous tiendrai au courant!
yardpenalty.com
@ yardpenalty.com, non, arrêter l'événement n'est pas le but! L'avertissement indique que vous avez placé votre écouteur sans spécifier s'il peut ou non empêcher le comportement par défaut de l'événement. Si vous souhaitez appeler preventDefault(), vous devez spécifier passive: false. Sinon, précisez passive: true. Vous obtenez uniquement l'avertissement si vous ne spécifiez pas non plus. Si vous spécifiez passive: trueet êtes preventDefault()appelé, cela entraîne une erreur et la valeur par défaut n'est pas empêchée. Spécifier passiven'est pas un hack ici. C'est la solution . C'est ce que l'avertissement demande!
tao
@tao merci pour le commentaire. Cela fait quelques années mais je me souviendrai certainement de la solution à l'avenir!
yardpenalty.com
1

Rencontrez également cela dans le plugin dropdown select2 de Laravel. Changer la valeur comme suggéré par Alfred Wallace de

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

à

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

résout le problème. Pourquoi il a un vote négatif, je ne sais pas mais ça marche pour moi.

Jun Salen
la source
0

Pour ceux qui sont coincés avec des problèmes hérités, recherchez la ligne qui renvoie l'erreur et ajoutez {passive: true}- par exemple:

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

devient

this.element.addEventListener(t, e, { passive: true} )
Alfred Wallace
la source
0

Pour jquery-ui-dragable avec jquery-ui-touch-punch, je l'ai corrigé comme pour Iván Rodríguez, mais avec un autre événement prioritaire pour 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
la source
-1

J'ai trouvé une solution qui fonctionne sur jQuery 3.4.1 slim

Après avoir réduit la taille, ajoutez {passive: true}à la fonction addEventListener sur la ligne 1567 comme suit :

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

Rien ne casse et les audits des phares ne se plaignent pas des auditeurs.

Mark Lancaster
la source
2
ne modifiez jamais le code source d'une bibliothèque; vous devez le remplacer à la place.
Raptor