Dla innego pytania ułożyłem tę odpowiedź , w tym ten przykładowy kod .
W tym kodzie używam kółka myszy do powiększania / zmniejszania płótna HTML5. Znalazłem kod, który normalizuje różnice szybkości między przeglądarką Chrome i Firefox. Jednak obsługa zoomu w Safari jest znacznie, znacznie szybsza niż w którymkolwiek z nich.
Oto kod, który obecnie mam:
var handleScroll = function(e){
var delta = e.wheelDelta ? e.wheelDelta/40 : e.detail ? -e.detail/3 : 0;
if (delta) ...
return e.preventDefault() && false;
};
canvas.addEventListener('DOMMouseScroll',handleScroll,false); // For Firefox
canvas.addEventListener('mousewheel',handleScroll,false); // Everyone else
Jakiego kodu mogę użyć, aby uzyskać tę samą wartość „delta” dla tej samej ilości ruchu kółka myszy w przeglądarkach Chrome 10/11, Firefox 4, Safari 5, Opera 11 i IE9?
To pytanie jest powiązane, ale nie ma dobrej odpowiedzi.
Edytować : dalsze badanie pokazuje, że jedno zdarzenie przewijania „w górę” to:
| evt.wheelDelta | evt.detail ------------------ + ---------------- + ------------ Safari v5 / Win7 | 120 | 0 Safari v5 / OS X | 120 | 0 Safari v7 / OS X | 12 | 0 Chrome v11 / Win7 | 120 | 0 Chrome v37 / Win7 | 120 | 0 Chrome v11 / OS X | 3 (!) | 0 (prawdopodobnie źle) Chrome v37 / OS X | 120 | 0 IE9 / Win7 | 120 | nieokreślony Opera v11 / OS X | 40 | -1 Opera v24 / OS X | 120 | 0 Opera v11 / Win7 | 120 | -3 Firefox v4 / Win7 | niezdefiniowany | -3 Firefox v4 / OS X | niezdefiniowany | -1 Firefox v30 / OS X | niezdefiniowany | -1
Co więcej, używanie gładzika MacBooka w systemie OS X daje różne rezultaty, nawet przy powolnym ruchu:
- W Safari i Chrome
wheelDelta
jest to wartość 3 zamiast 120 dla kółka myszy. - W przeglądarce Firefox
detail
jest to zwykle2
, czasami1
, ale przy bardzo powolnym przewijaniu ŻADNY WYDARZENIE NIE POWODUJE .
Więc pytanie brzmi:
Jaki jest najlepszy sposób na rozróżnienie tego zachowania (najlepiej bez żadnego klienta użytkownika lub podsłuchiwania systemu operacyjnego)?
źródło
e.wheelDelta/120
?Odpowiedzi:
Edytuj wrzesień 2014
Jeśli się uwzględni:
… Mogę tylko polecić użycie tego prostego kodu zliczającego znaki:
Oryginalna próba bycia poprawną następuje.
Oto moja pierwsza próba skryptu normalizacji wartości. Ma dwie wady w systemie OS X: Firefox na OS X wygeneruje wartości 1/3 takie, jakie powinny być, a Chrome na OS X wygeneruje wartości 1/40 takie, jakie powinny być.
Możesz przetestować ten kod we własnej przeglądarce tutaj: http://phrogz.net/JS/wheeldelta.html
Mile widziane są sugestie dotyczące wykrywania i ulepszania zachowania w przeglądarkach Firefox i Chrome w systemie OS X.
Edycja : jedną sugestią od @Tom jest po prostu policzenie każdego wywołania zdarzenia jako pojedynczego ruchu, używając znaku odległości, aby go dostosować. Nie da to świetnych rezultatów przy płynnym / przyspieszonym przewijaniu w systemie OS X, ani też nie poradzi sobie doskonale w przypadkach, gdy kółko myszy porusza się bardzo szybko (np.
wheelDelta
240), ale zdarza się to rzadko. Ten kod jest teraz zalecaną techniką pokazaną na początku tej odpowiedzi, z powodów tam opisanych.źródło
(((evt.deltaY <0 || evt.wheelDelta>0) || evt.deltaY < 0) ? 1 : -1)
nie jestem pewien, czego dowiaduje się z tego kontrola jakości.Oto moja szalona próba stworzenia spójnej i znormalizowanej delty między przeglądarkami (-1 <= delta <= 1):
Jest to całkowicie empiryczne, ale działa całkiem dobrze w Safari 6, FF 16, Opera 12 (OS X) i IE 7 w XP
źródło
event
-przedmiot wo
?o
Zmienna jest tam, aby pokazać chcemy oryginalnego zdarzenia, a nie zawinięte wydarzenie jak jQuery lub inne biblioteki mogą przechodzić do obsługi zdarzeń.Nasi znajomi z Facebooka opracowali świetne rozwiązanie tego problemu.
Przetestowałem na tabeli danych, którą buduję za pomocą React i przewija się jak masło!
To rozwiązanie działa w różnych przeglądarkach, w systemach Windows / Mac i w obu przy użyciu gładzika / myszy.
Kod źródłowy można znaleźć tutaj: https://github.com/facebook/fixed-data-table/blob/master/src/vendor_upstream/dom/normalizeWheel.js
źródło
Zrobiłem tabelę z różnymi wartościami zwracanymi przez różne zdarzenia / przeglądarki, biorąc pod uwagę DOM3
wheel
zdarzenie , które niektóre przeglądarki już obsługują (tabela poniżej).Na tej podstawie wykonałem tę funkcję, aby znormalizować prędkość:
http://jsfiddle.net/mfe8J/1/
Stół dla
mousewheel
,wheel
iDOMMouseScroll
zdarzeń:źródło
Kolejne, mniej lub bardziej samodzielne rozwiązanie ...
Nie wymaga to jednak uwzględnienia czasu między wydarzeniami. Niektóre przeglądarki wydają się zawsze uruchamiać zdarzenia z tą samą różnicą i po prostu uruchamiają je szybciej podczas szybkiego przewijania. Inni zmieniają delty. Można sobie wyobrazić adaptacyjny normalizator, który bierze pod uwagę czas, ale byłby nieco skomplikowany i niezręczny w użyciu.
Praca dostępna tutaj: jsbin / iqafek / 2
źródło
Proste i działające rozwiązanie:
źródło
Aby korzystać z funkcji zoom na urządzeniach dotykowych, zarejestruj się w przypadku zdarzeń Geststart, Gestchange i Gestendend i użyj właściwości event.scale. Możesz zobaczyć przykładowy kod .
W przypadku przeglądarki Firefox 17
onwheel
wydarzenie ma być obsługiwane przez wersje stacjonarne i mobilne (zgodnie z dokumentacją MDN na onwheel ). Również dla Firefoksa może byćMozMousePixelScroll
przydatne zdarzenie specyficzne dla Gecko (chociaż przypuszczalnie jest to teraz przestarzałe, ponieważ zdarzenie DOMMouseWheel jest teraz przestarzałe w Firefoksie).W systemie Windows wydaje się, że sam sterownik generuje zdarzenia WM_MOUSEWHEEL, WM_MOUSEHWHEEL (i może zdarzenie WM_GESTURE do przesuwania panelu dotykowego?). To wyjaśniałoby, dlaczego Windows lub przeglądarka nie wydają się normalizować samych wartości zdarzeń kółka myszy (i może oznaczać, że nie można napisać niezawodnego kodu w celu znormalizowania wartości).
Do obsługi zdarzeń
onwheel
( nie onmousewheel) w programie Internet Explorer dla IE9 i IE10 można również użyć standardowegoonwheel
zdarzenia W3C . Jednak jedno wycięcie może być wartością inną niż 120 (np. Pojedyncze wycięcie staje się 111 (zamiast -120) na mojej myszy przy użyciu tej strony testowej ). Napisałem kolejny artykuł z innymi szczegółami wydarzeń na kole, które mogą być istotne.Zasadniczo w moich własnych testach zdarzeń kółka (próbuję znormalizować wartości przewijania) stwierdziłem, że otrzymuję różne wartości dla systemu operacyjnego, producenta przeglądarki, wersji przeglądarki, typu zdarzenia i urządzenia (mysz Microsoft tiltwheel, gesty touchpada laptopa , touchpad laptopa z funkcją scrollzone, mysz Apple Magic Mouse, kulka przewijania myszy Apple Mighty Mouse, touchpad Mac itp.).
I trzeba zignorować różne efekty uboczne z konfiguracji przeglądarki (np. Firefox mousewheel.enable_pixel_scrolling, chrome --scroll-pixels = 150), ustawienia sterownika (np. Touchpad Synaptics) i konfiguracji systemu operacyjnego (ustawienia myszy Windows, preferencje myszy OSX, Ustawienia przycisku X.org).
źródło
To problem, z którym walczę od kilku godzin i to nie pierwszy raz :(
Próbowałem podsumować wartości za pomocą „machnięcia” i zobaczyć, jak różne przeglądarki zgłaszają wartości, i bardzo się one różnią, przy czym Safari zgłasza o rząd wielkości większe liczby na prawie wszystkich platformach, Chrome raportuje znacznie więcej (np. 3 razy więcej ) niż firefox, firefox jest zrównoważony na dłuższą metę, ale różni się między platformami na małych ruchach (na Ubuntu gnome, prawie tylko +3 lub -3, wygląda na to, że podsumowuje mniejsze zdarzenia, a następnie wysyła duże „+3”)
Obecnie znalezione rozwiązania to trzy:
Pomysł w Qooxdoo jest dobry i działa, i jest jedynym rozwiązaniem, które obecnie uważam za całkowicie spójne dla różnych przeglądarek.
Niestety ma tendencję do renormalizowania również przyspieszenia. Jeśli spróbujesz tego (w ich demach) i przewiniesz przez chwilę w górę iw dół z maksymalną prędkością, zauważysz, że przewijanie ekstremalnie szybkie lub bardzo wolne generuje prawie taką samą ilość ruchu. Z drugiej strony, jeśli ponownie załadujesz stronę i będziesz ją przesuwać bardzo powoli, zauważysz, że przewija się ona dość szybko ”.
Jest to frustrujące dla użytkownika Maca (takiego jak ja), który energicznie przesuwał po touchpadzie i spodziewając się, że dostanie się na górę lub dół przewijanej rzeczy.
Co więcej, ponieważ skaluje prędkość myszy w oparciu o maksymalną uzyskaną wartość, im bardziej użytkownik próbuje ją przyspieszyć, tym bardziej będzie spowalniać, podczas gdy użytkownik „powolnego przewijania” doświadczy dość dużej szybkości.
To sprawia, że to (skądinąd genialne) rozwiązanie jest nieco lepszą implementacją rozwiązania 1.
Przeportowałem rozwiązanie do wtyczki jquery mousewheel: http://jsfiddle.net/SimoneGianni/pXzVv/
Jeśli będziesz się nim bawić przez chwilę, zobaczysz, że zaczniesz uzyskiwać dość jednorodne wyniki, ale zauważysz również, że dość szybko osiąga on wartości + 1 / -1.
Pracuję teraz nad ulepszeniem go, aby lepiej wykrywał piki, tak aby nie wysyłały wszystkiego „poza skalę”. Byłoby również dobrze otrzymać wartość zmiennoprzecinkową z zakresu od 0 do 1 jako wartość delty, tak aby uzyskać spójne wyjście.
źródło
Zdecydowanie nie ma prostego sposobu na normalizację dla wszystkich użytkowników we wszystkich systemach operacyjnych i we wszystkich przeglądarkach.
Robi się gorzej niż twoje wymienione warianty - na mojej konfiguracji WindowsXP + Firefox3.6 moje kółko myszy wykonuje 6 na przewijanie o jeden stopień - prawdopodobnie dlatego, że gdzieś zapomniałem, że przyspieszyłem kółko myszy, albo w systemie operacyjnym, albo gdzieś w okolicy: config
Jednak pracuję nad podobnym problemem (przy okazji z podobną aplikacją, ale nie na płótnie) i pojawia się on po prostu używając znaku delta +1 / -1 i mierząc czas po ostatnim uruchomieniu, mieć szybkość przyspieszenia, tj. jeśli ktoś przewinie raz vs kilka razy w ciągu kilku chwil (założę się, że tak robią to mapy Google).
Koncepcja wydaje się działać dobrze w moich testach, po prostu dodaj do przyspieszenia mniej niż 100 ms.
źródło
źródło