2010-05-19 17 views
97

Parece que no puedo capturar el evento de desplazamiento en un iPad. Ninguno de estos trabajos, ¿qué estoy haciendo mal?javascript scroll event para iPhone/iPad?

window.onscroll=myFunction; 

document.onscroll=myFunction; 

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

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

Todos funcionan incluso en Safari 3 en Windows. Irónicamente, TODOS los navegadores de la PC son compatibles con window.onload= si no te importa atrapar los eventos existentes. Pero no ve en el iPad.

Respuesta

133

El iPhoneOS captura los eventos onscroll, excepto que no es la forma en que puede esperar.

panning con un solo dedo no genera ningún evento hasta que el usuario detiene panning-un evento onscroll se genera cuando la página deja de moverse y redibuja-tal como se muestra en la Figura 6-1.

Del mismo modo, desplazarse con 2 dedos dispara onscroll sólo después de haber dejado de desplazamiento.

La forma habitual de la instalación del controlador de obras, por ejemplo,

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

(Ver también https://developer.apple.com/library/content/documentation/AppleApplications/Reference/SafariWebContent/HandlingEvents/HandlingEvents.html)

+18

Gracias, eso me obligó a mirar más lejos en el problema. La verdadera respuesta fue la detección de la parte superior de la ventana en el iPhone/iPad sólo funciona con 'window.pageYOffset' y no ' document.body.scrollTop || document.documentElement.scrollTop' como cualquier otro navegador/hardware que exista. –

+5

@ck_ Desafortunadamente en el iPad 'window.pageYOffset' no se actualiza en la fase de desaceleración, sino solo cuando el desplazamiento finaliza. – Adaptabi

+2

Es una mala práctica sobreescribir window.onscroll directamente. Agregar un detector de eventos sería mejor. Use window.addEventListener ('scroll', function() {alert ('scrolled!');}); –

93

Para iOS es necesario utilizar el touchmove caso así como la desplazamiento evento como este:

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

Este evento solo se activa cuando el usuario está desplazándose activamente, no se dispara durante la fase de desaceleración del desplazamiento de cantidad de movimiento. –

+0

cambié el código para incluir el código de detección de desplazamiento final para iOS –

+0

También podría desear agregar un oyente para "touchend" que actuará de forma similar al desplazamiento en el escritorio. – BingeBoy

35

Lo siento por la adición de otra respuesta a una publicación anterior pero normalmente obtengo un evento de desplazamiento muy bien usando este código (funciona al menos en 6.1)

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

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

Y eso funciona para mí. Lo único que no hace es dar un evento de desplazamiento para la desaceleración del desplazamiento (una vez que se completa la desaceleración se obtiene un evento de desplazamiento final, haga lo que haga con él) pero si desactiva la inercia con css haciendo esto

-webkit-overflow-scrolling: none; 

no te dan la inercia de sus elementos, para el cuerpo, aunque es posible que tenga que hacer el clásico

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

¿Por qué rechazar una respuesta válida y no dejar un comentario explicando el problema con ella? –

+3

porque el downvoting es fácil y rápido. :/ –

+2

Una respuesta SIEMPRE es "válida" según su autor ... Nadie publica una respuesta intencionalmente inválida. Pero sí, deberían haber explicado por qué votaron negativamente. –

6

yo era capaz de obtener una gran solución a este problema con iScroll, con el sensación de impulso de desplazamiento y todo https://github.com/cubiq/iscroll El documento github es genial, y en su mayoría lo seguí. Aquí están los detalles de mi implementación.

HTML: Envolví el área de desplazamiento de mi contenido en algunos divs que iScroll puede utilizar:

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

CSS: utilicé la clase Modernizr para "toque" para apuntar a mi estilo solo cambia a dispositivos táctiles (porque solo instanciaba iScroll al tocar).

.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: que incluyen iscroll-probe.js de la descarga iScroll y, a continuación, inicializar el desplazador como abajo, donde updatePosition es mi función que reacciona a la nueva posición de desplazamiento.

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

Tienes que usar myScroller para obtener la posición actual ahora, en lugar de mirar el desplazamiento de desplazamiento. Aquí es una función tomado de http://markdalgleish.com/presentations/embracingtouch/ (un artículo muy útil, pero un poco fuera de fecha ahora)

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}; 
} 

La única otra Gotcha fue de vez en cuando iba a perder parte de mi página que yo estaba tratando de desplazarse a, y se negaría a desplazarse. Tuve que agregar algunas llamadas a myScroller.refresh() cada vez que cambiaba el contenido de la #wrapper, y eso resolvió el problema.

EDITAR: Otro problema es que iScroll come todos los eventos de "clic". Active la opción para que iScroll emita un evento "tap" y los administre en lugar de eventos "click". Afortunadamente, no necesité mucho hacer clic en el área de desplazamiento, así que esto no fue un gran problema.