2012-09-18 16 views
6

Utilizo preventDefault() en el inicio táctil del documento para evitar que se desplace en una página. Desafortunadamente esto evita demasiado. El usuario ya no puede enfocar una entrada (y abrir el teclado virtual). Usando jQuery focus(), puedo asignar el foco a la entrada en un touchstart. Esto abre el teclado virtual en iOS (la mayoría de las veces), pero nunca en Android.Impedir el desplazamiento en el navegador del dispositivo móvil, sin impedir el enfoque de la entrada

Antecedentes:

que tiene una página web que quiero hacer tanto como una aplicación móvil como sea posible. Solo me preocupan realmente Android e iOS, pero cualquier factor de forma. Empiezo por hacer que el contenido de la página sea exactamente del mismo tamaño que el tamaño de la pantalla. Esto es agradable hasta que el usuario ponga su dedo en la página. Necesito evitar el desplazamiento del usuario. El siguiente código logra esto, pero de maneras ligeramente diferentes en los dos sistemas operativos.

$(document).on('touchstart', function(e) { 
    e.preventDefault(); 
}); 

En iOS, esto impide el desplazamiento elástico: donde un usuario puede revelar una textura detrás de la página web, tratando de desplazarse fuera de la página. La característica es buena para una página web normal, pero en mi caso es perjudicial para UX.

En Android, evita la revelación de un truco útil que utilizo para ocultar la barra de direcciones. Los navegadores Android comienzan con la barra de direcciones visible, pero a medida que el usuario se desplaza hacia abajo, desaparece. Para forzar a que el navegador oculte la barra de direcciones, simplemente agregue esta línea de código a su función llamada load.

$('html, body').scrollTop(1); 

Ésta es una (pero también la única) hacky para decirle al navegador de Android que hemos desplazado, y la barra de direcciones ya no es necesario.

Sin preventDefault en el documento, el navegador de Android permitirá el desplazamiento y la barra de direcciones se puede revelar.

Por lo tanto, ambos sistemas operativos tienen una buena razón para solicitar prevent_fault() en cada entrada táctil del documento, pero previene demasiado. Al tocar en un campo de entrada no hace nada. Usar una llamada a jQuery focus() puede ayudar, pero solo abre el teclado virtual en iOS, no en Android.

$('input').on('touchstart', function() { 
    $(this).focus(); 
}); 

¿Cómo puedo evitar que la página de desplazamiento, pero el uso de la funcionalidad nativa del navegador para dar atención a los campos de entrada?

Nota: Este código

$(document).on('touchstart', function(e) { 
    if (e.target.nodeName !== 'INPUT') { 
     e.preventDefault(); 
    } 
}); 

es defectuoso porque el usuario puede desplazarse por la página siempre que el contacto inicial se origina desde dentro del campo de entrada.

Respuesta

8

De hecho, resolví este problema en otro proyecto, lo olvidé y lo recordé durante la mayor parte del tiempo escribiendo esto.

La clave es hacerlo en touchmove.

$(document).on('touchmove', function(e) { 
    e.preventDefault(); 
}); 

Sin embargo, preventDefault en touchstart hace todo tipo de cosas agradables como la prevención de la imagen de menú Guardar en una presentación de diapositivas permitido gesto. Mis proyectos también incluyen esto.

$(document).on('touchstart', function(e) { 
    if (e.target.nodeName !== 'INPUT') { 
     e.preventDefault(); 
    } 
}); 

Si alguien tiene algunas sugerencias sobre el contenido adicional o cómo cambiar el formato de este modo que pueda llegar a una mayor audiencia que sería grande. Nunca he visto el contenido que tengo aquí en un solo lugar, así que sentí que tenía que estar en SO.

0

¡Combine los dos!

// prevent scrolling from outside of input field 
$(document).on('touchstart', function(e) { 
    if (e.target.nodeName !== 'INPUT') { 
     e.preventDefault(); 
    } 
}); 

// prevent scrolling from within input field 
$(document).on('touchmove', function(e) { 
    if (e.target.nodeName == 'INPUT') { 
     e.preventDefault(); 
    } 
}); 

Esto probablemente no es perfecto tampoco, y estoy especialmente preocupado de que la primera función evitará siguientes enlaces, pero lo dejaré a otros a hacer pruebas exhaustivas.

0

La respuesta simple a su pregunta es no usar "preventDefault" en su lugar use la propiedad pointer-events css para deshabilitar el desplazamiento en el elemento que se desplaza.

CSS para sus entradas:

input { 
    pointer-events: auto !important; 
} 

touchstart detector de eventos:

document.body.addEventListener('touchstart', function(e) { 
    if (e.target.nodeName === 'INPUT') { 
     this.style.pointerEvents = 'none'; 
    } 
}); 

Usted tendrá que restablecer el puntero eventos cuando difuminar la entrada.

document.body.pointerEvents = 'auto'; 

+1 Buena pregunta

+0

Así que están cambiando el DOM en cada touchstart y en cada touchend. Quizás esta no sea la manera ligera, si consideramos las actuaciones. –

Cuestiones relacionadas