Domyślne szybkie przewijanie pokrętła

Sahel Sharify
Sahel Sharify

Aby poprawić działanie przewijania/powiększania w wheel, zachęcamy deweloperów do rejestrowania detektorów zdarzeń wheel i mousewheel jako pasywnych przez przekazanie opcji {passive: true} do addEventListener(). Zarejestrowanie detektorów zdarzeń jako pasywnych informuje przeglądarkę, że detektory kół nie wywołają elementu preventDefault(), a przeglądarka może bezpiecznie przewijać i powiększać widok bez blokowania detektorów.

Problem polega na tym, że detektory zdarzeń koła zębatego najczęściej są koncepcyjnie pasywne (nie wywołują preventDefault()), ale nie są wyraźnie określone jako takie, przez co przeglądarka musi czekać na zakończenie obsługi zdarzeń JS, zanim zacznie przewijać/powiększać, mimo że czekanie nie jest konieczne. W Chrome 56 naprawiliśmy ten błąd w przeglądarkach touchstart i touchmove. Z później wdrożyliśmy tę zmianę zarówno w przeglądarkach Safari, jak i Firefoksie. Jak widać na naszym demonstracyjnym filmie, zostawiając działanie, które spowodowało zauważalne opóźnienie reakcji przewijania. W Chrome 73 zastosowaliśmy tę samą ingerencję w zdarzenia wheel i mousewheel.

Interwencja

Celem tej zmiany jest skrócenie czasu potrzebnego na aktualizację wyświetlacza od momentu, gdy użytkownik zacznie przewijać ekran za pomocą kółka lub touchpada, bez konieczności zmiany kodu przez programistów. Nasze dane pokazują, że 75% odbiorników wheel i mousewheel zarejestrowanych na poziomie głównym (okno, dokument lub treść) nie określa żadnych wartości opcji pasywnej, a ponad 98% takich detektorów nie wywołuje preventDefault(). W Chrome 73 domyślnie zmieniamy detektory wheel i mousewheel zarejestrowane w głównych elementach docelowych (oknie, dokument lub treść) na pasywne. Oznacza to, że odbiornik takiego jak:

window.addEventListener("wheel", func);

jest odpowiednikiem:

window.addEventListener("wheel", func, {passive: true});

Wywołanie metody preventDefault() w detektorze zostanie zignorowane wraz z tym ostrzeżeniem dotyczącym Narzędzi deweloperskich:

[Intervention] Unable to preventDefault inside passive event listener due
to target being treated as passive. See https://www.chromestatus.com/features/6662647093133312

Naprawa i wskazówki

W większości przypadków nie można zaobserwować uszkodzenia. Tylko w rzadkich przypadkach (według naszych danych jest to mniej niż 0,3% stron) może nastąpić niezamierzone przewijanie lub powiększenie, ponieważ wywołanie preventDefault() jest ignorowane w odbiornikach, które są domyślnie uznawane za pasywne. Twoja aplikacja może określić, czy wysyła ją w środowisku, sprawdzając, czy wywołanie metody preventDefault() miało wpływ za pomocą właściwości defaultPrevented. Rozwiązanie tego problemu jest stosunkowo łatwe: przekaż {passive: false} do addEventListener(), aby zastąpić domyślne działanie i zachować odbiornik jako blokowanie.