www style site pure org oficial official examples benefits css web-applications

css - style - Aplicación web para iPhone-Detener el desplazamiento del cuerpo



w3c web standards (6)

Estoy creando una aplicación web para iPhone y ahora, desde iOS5, puedes usar position: fixed; para encabezados etc. etc.

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

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

PD: Solo quiero que una cosa deje de desplazarse, tengo un div llamado #contenedor que todavía quiero tener la capacidad de desplazarme.


Como otros sugirieron, escribí una función rápida que golpea mi div de desplazamiento un píxel cada vez que se desplaza hacia la parte superior o inferior para evitar que se arrastre toda la página. Eso está bien para mi div de desplazamiento, pero los divs fijos en mi página aún eran susceptibles de arrastrar la página. Accidentalmente me di cuenta de que cuando colocaba un div fijo en la parte superior de mi div de desplazamiento (que ya no arrastraba la página debido a mi función de bump), los eventos de arrastre táctil pasaban a través del div fijo al div de desplazamiento por debajo y ese div fijo no era ya un potencial dragger de página. En base a eso, pensé que podría ser posible usar un div de desplazamiento de pantalla completa en el fondo como la base de toda la página para que todo el arrastre sea pasado y mis elementos reales en la parte superior estén seguros. La división div necesita realmente desplazarse, así que coloqué una división de relleno en su interior y la hice un poco más grande para garantizar que se desplaza. ¡Y funcionó! A continuación se muestra un ejemplo que utiliza esta idea para evitar que la página se arrastre. Lo siento si esto es obvio o ya se publicó, pero no lo vi en ningún otro lugar y realmente mejoró mi aplicación web. Por favor, pruébalo y hazme saber si te ayuda.

<html> <head> <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no"> <style> .myDiv { position:absolute; left:0; width:100%; color:white; } .myDiv.hidden { top:0; height:100%; -webkit-overflow-scrolling:touch; overflow-y:scroll; } .myDiv.title { top:0; height:30%; background-color:#6297BC; } .myDiv.scroll { bottom:0; height:70%; -webkit-overflow-scrolling:touch; overflow-y:scroll; background-color:#ADADAD; } </style> <script> function setup() { hiddenScrollingDiv.addEventListener("scroll", preventWindowScroll); visibleScrollingDiv.addEventListener("scroll", preventWindowScroll); hiddenScrollingDiv.style.height=window.innerHeight; visibleScrollingDiv.style.height=parseInt(window.innerHeight*.7)+1; fillerDiv.style.height=window.innerHeight+2; hiddenScrollingDiv.scrollTop=1; visibleScrollingDiv.scrollTop=1; } function preventWindowScroll(evt) { if (evt.target.scrollTop==0) evt.target.scrollTop=1; else if (evt.target.scrollTop==(evt.target.scrollHeight-parseInt(evt.target.style.height))) evt.target.scrollTop=evt.target.scrollHeight-parseInt(evt.target.style.height)-1; } </script> </head> <body onload="setup()"> <div id="hiddenScrollingDiv" class="myDiv hidden"><div id="fillerDiv"></div></div> <div id="visibleTitleDiv" class="myDiv title"><br><center>Non-scrolling Div</center></div> <div id="visibleScrollingDiv" class="myDiv scroll"> <ul> <li style="height:50%">Scrolling Div</li> <li style="height:50%">Scrolling Div</li> <li style="height:50%">Scrolling Div</li> </ul> </div> </body> </html>


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 una corrección para que el elemento dado ya no cause un rebote elástico en todo el cuerpo cuando se desplaza por sus extremos.

bouncefix.remove (el)

Eliminar a todos los oyentes / observadores responsables de arreglar el rebote elástico de todo el cuerpo.

¿Por qué?

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

  1. Solo funcionaba 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 expuso un método para eliminar los escuchas. 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 se produce cuando se encuentra en uno de los extremos de desplazamiento. En touchstart, observamos 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 somos capaces de establecer el valor de scrollTop. Si el contenido aún no es desplazable, por ejemplo, solo tiene 1 elemento de lista, todo el cuerpo se desplazará nuevamente. Bouncefix.js se encargará de todo esto en segundo plano mediante el uso de la delegación de eventos y la comprobación de scrollHeight contra offsetHeight en cualquier momento en que se inicie el inicio táctil. En el caso de que no haya contenido desplazable, todo el desplazamiento en el contenedor se bloquea con e.preventDefault ();


Intente poner esto en la parte superior de su archivo JS ..

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

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

Fuente: ¿ Detiene UIWebView de "rebotar" verticalmente?


Una solución previa sugirió:

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. Detectar cuándo se ha desplazado la parte superior / inferior de un elemento de interés (por ejemplo, modal).
  2. Si se ha desplazado hacia abajo, use la técnica preventDefault anterior para el evento uponuchmove, pero SOLO SI, el usuario intenta desplazarse hacia abajo.
  3. Si el usuario intenta desplazarse hacia arriba, no preventDefault defecto.
  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 por conveniencia (probado con vanilla JS / React en iOS mobile / desktop safari, así como Android / Desktop Chrome).

Visite https://medium.com/jsdownunder/locking-body-scroll-for-all-devices-22def9615177 para obtener una explicación más detallada de los diferentes enfoques.


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é usando un delegado, ya que también está atrapado en el documento pero cancelado en el último segundo.

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


Actualizar:

Este problema ha sido un dolor 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 de mis preguntas: Prevenir el toque predeterminado de los padres pero no de los niños .

Espero que ayude a algunas personas.

Respuesta original:

En realidad estoy investigando exactamente el mismo problema y me he encontrado con esto:

Scrollfix

Lo he probado y funciona casi perfectamente. Si copia todo el código en una demostración y lo prueba en iOS, no verá el fondo gris a menos que tome la barra negra e intente desplazarse por ella. Sin embargo, debería ser bastante fácil usar el código que Ben proporcionó para evitar que eso suceda (preventDefault ()).

Espero que ayude (¡Definitivamente me ha ayudado!) Será :)