Пометьте обработчик событий как пассивный, чтобы сделать страницу более отзывчивой

217

Я использую молоток для перетаскивания, и он загружается другими вещами, как это предупреждающее сообщение говорит мне.

Обработка события ввода «touchstart» была отложена на X мс из-за того, что основной поток занят. Пометьте обработчик событий как пассивный, чтобы сделать страницу более отзывчивой.

Поэтому я попытался добавить «пассивный» слушателю так

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

но я все еще получаю это предупреждение.

Matt
источник

Ответы:

266

Для тех, кто получает это предупреждение впервые, это связано с новейшей функцией Passive Event Listeners , которая была реализована в браузерах сравнительно недавно (лето 2016 года). С https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md :

Пассивные прослушиватели событий - это новая функция в спецификации DOM, которая позволяет разработчикам подключаться для повышения производительности прокрутки, устраняя необходимость в прокрутке, чтобы блокировать приемники событий касания и прокрутки. Разработчики могут пометить слушателей касанием и колесом с помощью {passive: true}, чтобы указать, что они никогда не будут вызывать warnDefault. Эта функция поставляется в Chrome 51, Firefox 49 и включена в WebKit. Для полного официального объяснения читайте больше здесь.

Смотрите также: Что такое пассивные слушатели событий?

Возможно, вам придется подождать, пока ваша библиотека .js не осуществит поддержку.

Если вы обрабатываете события косвенно через библиотеку JavaScript, вы можете зависеть от поддержки этой библиотеки этой функцией. По состоянию на декабрь 2019 года, похоже, что ни одна из основных библиотек не реализовала поддержку. Некоторые примеры:

Ансон Као
источник
16
как насчет ионных библиотек?
abhit
10
Я звоню preventDefault()- возможно ли подавить это предупреждение?
Maja
12
Google Maps JavaScript API версии 3 также генерирует эти предупреждения. Проблема отслеживается на сайте issetracker.google.com/issues/63211698 . (Довольно иронично, учитывая, что Google Chrome предупреждает о нарушениях, которые генерирует JavaScript API Карт Google.)
Йохем Шуленклоппер
6
чтобы подавить это предупреждение, вы можете `addEventListener ('touchstart', this.callPassedFuntion, {passive: false})`
Шломи Шварц
9

Это скрывает предупреждение:

jQuery.event.special.touchstart = {
  setup: function( _, ns, handle ) {
      this.addEventListener("touchstart", handle, { passive: !ns.includes("noPreventDefault") });
  }
};
Иван Родригес
источник
6
Разве цель не состоит в том, чтобы остановить фактическое событие? Я не хотел бы скрывать сообщение, пока я не обработал проблему.
yardpenalty.com
1
Я думаю, что это проблема библиотеки jquery. Я думаю, что разработчики должны это исправить. Но если вы получите это, дайте мне знать, как это сделать, пожалуйста. Огромное спасибо.
Иван Родригес
Наверняка Иван! Да, это так. Эй, теперь мне любопытно ... Я использую плагин d3, и я получаю около 2300 нарушений. Может быть, ваш код поможет! Я буду держать вас в курсе!
yardpenalty.com
@ yardpenalty.com, нет, остановка мероприятия не является целью! В предупреждении говорится, что вы поместили слушателя без указания того, может ли это предотвратить поведение по умолчанию для события. Если у вас есть случаи, когда вы хотите позвонить preventDefault(), вы должны указать passive: false. Если нет, уточните passive: true. Вы получите предупреждение, только если не укажете. Если вы укажете passive: trueи preventDefault()вызовете его, это приведет к ошибке и по умолчанию не будет предотвращено. Указание passiveздесь не является взломом. Это решение . Это то, что просит предупреждение!
Тао
@tao спасибо за комментарий. Прошло несколько лет, но я обязательно запомню решение в будущем!
yardpenalty.com
1

Также столкнитесь с этим в выпадающем плагине select2 в Laravel. Изменение значения в соответствии с предложением Альфреда Уоллеса из

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

в

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

решает проблему. Почему у него отрицательный голос, я не знаю, но у меня это работает.

Июн сален
источник
0

Для тех, кто застрял с унаследованными проблемами, найдите строку с ошибкой и добавьте, {passive: true}например:

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

становится

this.element.addEventListener(t, e, { passive: true} )
Альфред Уоллес
источник
0

Для jquery-ui-dragable с помощью jquery-ui-touch-punch я исправил его аналогично Iván Rodríguez, но с еще одним переопределением событий для 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
источник
-1

Я нашел решение, которое работает на JQuery 3.4.1 Slim

После отмены минимизации добавьте {passive: true}функцию addEventListener в строку 1567 следующим образом:

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

Ничто не ломается, и проверки маяков не жалуются на слушателей.

Марк Ланкастер
источник
2
никогда не меняйте исходный код библиотеки; Вы должны переопределить это вместо этого.
Raptor