2012-02-02 23 views
5

Actualmente estoy trabajando en una aplicación web de una sola página optimizada para dispositivos táctiles, principalmente iOS. Implementé el nuevo desplazamiento nativo de iOS a través del -webkit-overflow-scrolling: touch; y todo funciona bien, excepto que todavía estamos experimentando el efecto de desplazamiento elástico de Apple en todo el cuerpo de la página.Deshabilitar el desplazamiento del cuerpo elástico de iOS y mantener el desplazamiento nativo funcionando

Esto implica que toda la página se mueva fuera de la parte superior/inferior de la ventana gráfica cuando termina un desplazamiento o se empuja el cuerpo y realmente se revela el hecho de que se trata de una aplicación web. He seguido various guidelines para evitar esto y, mientras lo hacen, impiden que los elementos desplazables internos funcionen por completo.

Here's a fiddle para demostrar lo que estoy usando hasta ahora.

¿Alguien ha encontrado una solución que deshabilita el desplazamiento elástico del cuerpo pero permite que funcionen los scrollables internos?

+0

Noté que se inhabilitó la desactivación de touchmove para $ (documento). ¿Esto es a propósito? – zvona

+0

Lo es. Si deja de comentar, se deshabilita todo el desplazamiento. Lo siento, debería haber mencionado eso. – madcapnmckay

Respuesta

5

He adaptado la buena solución de Conditionally block scrolling/touchmove event in mobile safari usando Dojo:

var initialY = null; 
dojo.connect(document, 'ontouchstart', function(e) { 
    initialY = e.pageY; 
}); 
dojo.connect(document, 'ontouchend', function(e) { 
    initialY = null; 
}); 
dojo.connect(document, 'ontouchcancel', function(e) { 
    initialY = null; 
}); 
dojo.connect(document, 'ontouchmove', function(e) { 
    if(initialY !== null) { 
     if(!dojo.query(e.target).closest('#content')[0]) { 
      // The element to be scrolled is not the content node 
      e.preventDefault(); 
      return; 
     } 

     var direction = e.pageY - initialY; 
     var contentNode = dojo.byId('content'); 

     if(direction > 0 && contentNode.scrollTop <= 0) { 
      // The user is scrolling up, and the element is already scrolled to top 
      e.preventDefault(); 
     } else if(direction < 0 && contentNode.scrollTop >= contentNode.scrollHeight - contentNode.clientHeight) { 
      // The user is scrolling down, and the element is already scrolled to bottom 
      e.preventDefault(); 
     } 
    } 
}); 

El elemento que se ha desplegado se # contenido en este caso.

+1

¿Estás seguro de que esto funciona? No podría replicar esto trabajando en violín ... preguntándome si esta es de hecho una respuesta correcta – zanona

+0

Todavía funciona bastante bien para mí. –

+0

En IOS 7, este código solo evitará el desplazamiento elástico una vez que la página se haya desplazado más allá de sus límites una vez. Por ejemplo: 1. se desplaza hacia abajo: se overscrolls 2. se desplaza hacia abajo una vez más: no Permitir desplazamiento 3. se desplaza hacia arriba: se overscrolls 4. se desplaza hacia abajo: se overscrolls 5.se desplaza hacia abajo: no se sobrescribe 6. se desplaza hacia abajo: no se sobrescribe – Phedg1

1

Tal iScroll es lo que está buscando (si Tengo tu pregunta correcta)

+0

El problema con iscroll es que no es nativo y solo implementa el desplazamiento en un contenedor hasta donde yo sé. El desplazamiento de desbordamiento de webkit permite el desplazamiento táctil nativo en contenedores y funciona muy bien. Pero el desplazamiento del cuerpo elástico de Apple todavía está presente sin importar qué solución de desplazamiento elija. – madcapnmckay

+0

En realidad, iScroll no lo sufre, creo que pone una solución en su lugar, esencialmente desactiva todo el desplazamiento y luego agrega sus controladores en la parte superior para permitir su desplazamiento. Estoy buscando hacer lo mismo pero solo dejo que el desplazamiento nativo continúe. – madcapnmckay

0

A riesgo de duplicar mi post, trato de resolver el mismo problema y hasta ahora sólo soy tan lejos:

 $(document).bind("touchmove",function(e){ 
      e.preventDefault(); 
     }); 
     $('.scrollable').bind("touchmove",function(e){ 
      e.stopPropagation(); 
     }); 

Esto funciona si tiene un elemento de desbordamiento que no cubre toda la pantalla , como en una aplicación para iPad, por ejemplo. pero no funciona si tienes una aplicación móvil y toda la ventana gráfica está cubierta por tu elemento desbordado.

Lo único que podía pensar es comprobar la scrollTop() del $ ('desplazable') y luego unirse condicionalmente la preventDefault() si es 0.

Después de probar, me di cuenta de que la webkit UA informa scrollTop siempre como 0 cuando el elemento se desplaza hacia arriba incluso cuando hace el "rebote interno" del desplazamiento de desbordamiento nativo. Así que no puedo hacer nada ya que necesitaría un scrollTop negativo para configurar mi condición.

suspiro. Frustrante.

Cuestiones relacionadas