2010-05-19 17 views
97

Nie mogę uchwycić zdarzenia przewijania na iPadzie. Żadna z tych rzeczy nie działa, co robię źle?Zdarzenie przewijania javascript na iPhone'a/iPada?

window.onscroll=myFunction; 

document.onscroll=myFunction; 

window.attachEvent("scroll",myFunction,false); 

document.attachEvent("scroll",myFunction,false); 

Wszystkie działają nawet w przeglądarce Safari 3 w systemie Windows. Jak na ironię, KAŻDY przeglądarka na PC obsługuje window.onload=, jeśli nie przeszkadza ci wrzucanie istniejących zdarzeń. Ale nie idź na iPada.

Odpowiedz

133

iPhoneOS przechwytuje zdarzenia onscroll, z wyjątkiem sytuacji niezgodnych z oczekiwaniami.

jednego palca płukanie nie generuje zdarzenia aż użytkownik przestaje panningu-onscroll zdarzenie jest generowane gdy strona zatrzymuje się i przerysowanie, jak pokazano na Figurze 6-1.

Podobnie przewijanie z 2 palców wystrzeliwuje onscroll dopiero po zatrzymaniu przewijania.

Zazwyczaj sposób obsługi instalacji pracuje np

window.addEventListener('scroll', function() { alert("Scrolled"); }); 
// or 
$(window).scroll(function() { alert("Scrolled"); }); 
// or 
window.onscroll = function() { alert("Scrolled"); }; 
// etc 

(Patrz także https://developer.apple.com/library/content/documentation/AppleApplications/Reference/SafariWebContent/HandlingEvents/HandlingEvents.html)

+18

Dzięki, że zmusił mnie do dalszego spojrzenia na problem. Prawdziwa odpowiedź została wykrywania szczyt rzutni na iPhone/iPad działa tylko z 'window.pageYOffset' i nie ' document.body.scrollTop || document.documentElement.scrollTop' jak każda inna przeglądarka/sprzęt w istnieniu. –

+5

@ck_ Niestety na IPAD 'window.pageYOffset' nie jest aktualizowany w fazie zwalniania, ale tylko po zakończeniu przewijania. – Adaptabi

+2

Zła praktyka bezpośrednio zastępuje window.onscroll. Dodanie detektora zdarzeń byłoby lepsze. Użyj window.addEventListener ('scroll', function() {alert ('scrolled!');}); –

93

dla iOS trzeba użyć touchmove zdarzenie jak również przewijania imprezy jak ta:

document.addEventListener("touchmove", ScrollStart, false); 
document.addEventListener("scroll", Scroll, false); 

function ScrollStart() { 
    //start of scroll event for iOS 
} 

function Scroll() { 
    //end of scroll event for iOS 
    //and 
    //start/end of scroll event for other browsers 
} 
+31

To zdarzenie jest uruchamiane tylko wtedy, gdy użytkownik aktywnie przewija, nie jest strzelane podczas fazy zwalniania przewijania pędu. –

+0

Zmieniłem kod tak, aby zawierał kod wykrywania końca przewijania dla iOS –

+0

Możesz również dodać detektor dla "touchend", który będzie działać jak przewijanie na pulpicie. – BingeBoy

35

żal dodając kolejną odpowiedź do starego posta, ale zazwyczaj uzyskuję bardzo dobre przewijanie przy użyciu tego kodu (działa co najmniej w wersji 6.1)

element.addEventListener('scroll', function() { 
    console.log(this.scrollTop); 
}); 

// This is the magic, this gives me "live" scroll events 
element.addEventListener('gesturechange', function() {}); 

To działa dla mnie. Jedyne, czego nie robi, to wydarzenie przewijania zwalniające przewijanie (gdy spowolnienie zostanie zakończone, otrzymasz końcowe zdarzenie przewijania, wykonaj to, co zechcesz), ale jeśli wyłączysz bezwładność za pomocą css, robiąc to,

-webkit-overflow-scrolling: none; 

nie dostaniesz bezwładność na swoich elementów, dla ciała, choć może trzeba zrobić klasyczny

document.addEventListener('touchmove', function(e) {e.preventDefault();}, true); 
+7

Po co zignorować poprawną odpowiedź i nie zostawiać komentarza wyjaśniającego problem? –

+3

, ponieważ likwidacja jest łatwa i szybka. :/ –

+2

Odpowiedź jest ZAWSZE "poprawna" zgodnie z jej autorem ... Nikt nie publikuje świadomie nieważnej odpowiedzi. Ale owszem, powinni wyjaśnić, dlaczego nie głosowali. –

6

I był w stanie uzyskać doskonałe rozwiązanie tego problemu z iScroll, z Poczucie przewijania pędu i wszystko, co trzeba. https://github.com/cubiq/iscroll Doktor github jest świetny, a ja głównie go śledziłem. Oto szczegóły mojej implementacji.

HTML: I owinął przewijalną obszar moich treści w niektórych div że iScroll może używać:

<div id="wrapper"> 
    <div id="scroller"> 
    ... my scrollable content 
    </div> 
</div> 

CSS: użyłem klasy modernizr dla "dotyk", aby kierować mój styl zmienia się tylko na urządzenia dotykowe (ponieważ zainicjowałem tylko iScroll po dotyku).

.touch #wrapper { 
    position: absolute; 
    z-index: 1; 
    top: 0; 
    bottom: 0; 
    left: 0; 
    right: 0; 
    overflow: hidden; 
} 
.touch #scroller { 
    position: absolute; 
    z-index: 1; 
    width: 100%; 
} 

JS: włączyłem iscroll-probe.js od pobrania iScroll, a następnie zainicjowany scroller jak poniżej, gdzie updatePosition jest moja funkcja, która reaguje na nową pozycję przewijania.

# coffeescript 
if Modernizr.touch 
    myScroller = new IScroll('#wrapper', probeType: 3) 
    myScroller.on 'scroll', updatePosition 
    myScroller.on 'scrollEnd', updatePosition 

Musisz użyć myScroller, aby uzyskać aktualną pozycję, zamiast patrzeć na przesunięcie przewijania. Oto funkcja pochodzi z http://markdalgleish.com/presentations/embracingtouch/ (super pomocny artykuł, ale trochę nieaktualne teraz)

function getScroll(elem, iscroll) { 
    var x, y; 

    if (Modernizr.touch && iscroll) { 
    x = iscroll.x * -1; 
    y = iscroll.y * -1; 
    } else { 
    x = elem.scrollTop; 
    y = elem.scrollLeft; 
    } 

    return {x: x, y: y}; 
} 

Jedyna haczyka był sporadycznie chciałbym stracić część mojej stronie, że starał się przejść do i odmówiłby przewijania. Musiałem dodać kilka wywołań myScroller.refresh() za każdym razem, gdy zmieniłem zawartość #wrapper, i to rozwiązało problem.

EDYCJA: Kolejnym problemem było to, że iScroll zjada wszystkie zdarzenia "kliknięcia". Włączyłem opcję, aby program iScroll emitował zdarzenie "stuknij" i obsłużyło zdarzenia zamiast "kliknij". Na szczęście nie potrzebowałem wiele klikania w obszarze przewijania, więc to nie była wielka sprawa.

Powiązane problemy