Domyślne szybkie przewijanie pokrętła

Sahel Sharify
Sahel Sharify

Aby poprawić działanie przewijania i powiększania wheel, zalecamy rejestrowanie detektorów zdarzeń wheelmousewheel jako pasywnych, podając opcję {passive: true} jako addEventListener(). Rejestrowanie detektorów zdarzeń jako pasywnych informuje przeglądarkę, że detektory koła nie będą wywoływać metody preventDefault(), a przeglądarka może bezpiecznie przewijać i powiększać bez blokowania detektorów.

Problem polega na tym, że przetwarzanie zdarzeń związanych z kołem jest najczęściej w koncepcji pasywne (nie wywołuje funkcji preventDefault()), ale nie jest wyraźnie tak określone, co powoduje, że przeglądarka musi czekać na zakończenie przetwarzania zdarzenia JS, zanim zacznie przewijać lub powiększać obraz, mimo że oczekiwanie nie jest konieczne. W Chrome 56 poprawiliśmy ten błąd w przypadku touchstarttouchmove, a ta zmiana została później zaadaptowana przez Safari i Firefox. Jak widać na filmie demonstracyjnym, który nagraliśmy w tamtym czasie, zachowanie pozostawione bez zmian spowodowało zauważalne opóźnienie w reakcji na przewijanie. W Chrome 73 zastosowaliśmy te same środki zaradcze do zdarzeń wheelmousewheel.

Interwencja

Celem tej zmiany jest skrócenie czasu potrzebnego na aktualizację wyświetlacza po rozpoczęciu przewijania za pomocą kółka lub touchpada, bez konieczności zmiany kodu. Nasze dane wskazują, że 75% wydarzeń wheelmousewheel zarejestrowanych na korzeniach obiektów docelowych (window, document lub body) nie określa żadnych wartości dla opcji passive, a ponad 98% takich uchwytów nie wywołuje metody preventDefault(). W Chrome 73 zmieniamy tak, aby komponenty wheelmousewheel zarejestrowane na elementach korzenia (okno, dokument lub body) były domyślnie pasywne. Oznacza to, że detektor zdarzeń:

window.addEventListener("wheel", func);

staje się równoważny następującemu wyrażeniu:

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

Wywołanie preventDefault() w słuchaczu zostanie zignorowane, a w Narzędziach deweloperskich pojawi się to ostrzeżenie:

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

Uszkodzenia i wskazówki

W większości przypadków nie dochodzi do żadnych naruszeń. Tylko w rzadkich przypadkach (według naszych danych mniej niż 0,3% stron) może wystąpić niezamierzone przewijanie lub powiększanie, ponieważ wywołanie preventDefault() jest ignorowane w słuchaczach, które są domyślnie traktowane jako pasywne. Aplikacja może określić, czy jest to problem występujący w naturze, sprawdzając, czy wywołanie funkcji preventDefault() miało jakikolwiek wpływ na usługę defaultPrevented. Rozwiązanie problemu w przypadku dotkniętych przypadków jest stosunkowo proste: prześlij {passive: false} do addEventListener(), aby zastąpić domyślne działanie i zachować blokowanie przez listenera zdarzeń.