Aplicación web iPhone: detener el desplazamiento del cuerpo

Estoy creando una aplicación web para iPhone y ahora, desde iOS5, puede usar la posición: fija; para encabezados, etc.

Aunque funciona, si se desplaza hacia arriba en la parte superior de la página, muestra el área gris habitual durante un tiempo antes de que ya no pueda desplazarse

Ejemplo

¿Hay alguna manera de detener este desplazamiento? He intentado cosas como desbordamiento: oculto; pero parece que no puedo encontrar nada.

PD: Solo quiero que una cosa deje de desplazarse, tengo un div llamado #container que aún quiero tener la capacidad de desplazar.

Después de revisar varias soluciones, comencé a crear una solución personalizada:

bouncefix.js

http://jaridmargolin.github.io/bouncefix.js/

Uso:

bouncefix.add (el)

Aplique la solución para que el elemento dado ya no provoque un rebote elástico de todo el cuerpo cuando se desplaza en sus extremos.

bouncefix.remove (el)

Elimine a todos los oyentes / observadores responsables de reparar el rebote elástico de todo el cuerpo.

¿Por qué?

Scrollfix fue un buen comienzo, sin embargo, noté varios problemas:

  1. Solo funcionó cuando había contenido desplazable. Si tuviera una página vacía, se produciría el efecto de rebote en el cuerpo.
  2. La API no expone un método para eliminar los oyentes. Mi aplicación tendrá varias páginas, y no se sentía bien mantener a todos los oyentes conectados mientras el usuario se movía alrededor de la aplicación.

¿Cómo?

Utiliza un enfoque similar al de scrollfix. El problema ocurre cuando te encuentras en uno de los extremos de desplazamiento. En touchstart, buscamos si estamos en el extremo superior o extremo inferior, agregando 1px si estamos en la parte superior y eliminando 1px si estamos en la parte inferior.

Desafortunadamente, este truco solo funciona si podemos establecer el valor de scrollTop. Si el contenido aún no se puede desplazar, por ejemplo, solo tiene 1 elemento de lista, todo el cuerpo se desplazará nuevamente. Bouncefix.js se encargará de todo esto detrás de escena utilizando la delegación de eventos y comprobando scrollHeight contra el desplazamiento. Height siempre que se active touchstart. En el caso de que no haya contenido desplazable, todo el desplazamiento en el contenedor se bloquea con e.preventDefault ();

lo que funcionó para mí:

html, body, .scrollable { overflow: auto; -webkit-overflow-scrolling: touch; } 

más (usando jQuery …)

 $(function() { $(document).on("touchmove", function(evt) { evt.preventDefault() }); $(document).on("touchmove", ".scrollable", function(evt) { evt.stopPropagation() }); }); 

es importante que la llamada evt.stopPropagation() esté utilizando un delegado, ya que también se encuentra en el documento, pero se cancela en el último segundo.

En efecto, esto capta todos los eventos de touchmove en el documento, pero si el evento original se .scrollable un .scrollable simplemente stopPropagation de stopPropagation lugar de cancelar el evento.

Intenta poner esto en la parte superior de tu archivo JS ..

 document.ontouchmove = function(event){ event.preventDefault(); } 

Esto evitará que puedas desplazarte por la página, por lo que no podrás ver el “área gris” en la parte superior.

Fuente: ¿ Detener UIWebView de “rebote” verticalmente?

Actualizar:

Este problema ha sido un problema para mucha gente, pero aquí hay una solución sólida creada por bjrn :

Demostración: http://rixman.net/demo/scroll/
Y hay una discusión al respecto aquí: https://github.com/joelambert/ScrollFix/issues/2

Esto fue publicado originalmente por Ryan en respuesta a una pregunta mía: Impedir touchmove default en parent pero no child .

Espero que eso ayude a algunas personas.


Respuesta original:

De hecho estoy investigando el mismo problema y me he encontrado con esto:

https://github.com/joelambert/ScrollFix

Lo probé y funciona casi a la perfección. Si copias todo el código en una demostración y le das una oportunidad en iOS, no verás el fondo gris a menos que agarres la barra negra e intentes desplazar eso. Sin embargo, debería ser bastante fácil usar el código proporcionado por Ben para evitar que eso ocurra (preventDefault ()).

Espero que ayude (¡Definitivamente me ha ayudado!) 🙂

Al igual que otros sugirieron que escribí una función rápida que golpea mi div desplazable un píxel cada vez que se desplaza hacia arriba o hacia abajo para evitar que la página entera se arrastre. Eso está bien para mi div de desplazamiento pero los divs fijos en mi página todavía eran susceptibles al arrastre de la página. Accidentalmente noté que cuando colocaba un divisor fijo en la parte superior de mi div desplazable (que ya no arrastraba la página debido a mi función de relieve), los eventos de arrastre se pasaban a través del div fijo al div desplazable y el div fijo no era más un posible dragger de página. Sobre la base de eso, pensé que sería posible usar un desplazamiento de pantalla completa div en el fondo como base para toda la página, de modo que todo el arrastre pasaría y mis elementos reales arriba serían seguros. La base div necesita realmente desplazarse, así que coloqué un divisor de relleno dentro de ella y lo hice un poco más grande para garantizar que se desplaza. ¡Y funcionó! A continuación se muestra un ejemplo con esta idea para evitar el arrastre de páginas. Lo siento si esto es obvio o ya está publicado, pero no vi esto en ningún otro lado y realmente mejoró mi aplicación web. Pruébelo y avíseme si ayuda.

         

Non-scrolling Div
  • Scrolling Div
  • Scrolling Div
  • Scrolling Div

Una solución anterior sugerida:

 document.ontouchmove = function(event){ event.preventDefault(); } 

Sin embargo, esto también detiene el desplazamiento del elemento de interés.

Para superar esto, se puede hacer lo siguiente:

  1. Detecta cuándo se ha desplazado la parte superior / inferior de un elemento de interés (por ejemplo, modal).
  2. Si se desplazó hacia abajo, use la técnica preventDefault anterior para el evento ontouchmove, pero SÓLO SI, el usuario intenta desplazarse hacia abajo más.
  3. Si el usuario intenta desplazarse hacia arriba, no preventDefault más.
  4. Viceversa se aplica si se desplaza hacia arriba.

Aquí está el código fuente para una implementación de la lógica anterior.

El paquete npm también se puede descargar para mayor comodidad (probado con JS / React vainilla en iOS móvil / safari de escritorio, así como Android / Desktop Chrome).

Consulte https://medium.com/jsdownunder/locking-body-scroll-for-all-devices-22def9615177 para obtener más información sobre los diferentes enfoques.