javascript - para - phonegap
¿Cómo implementar mi propia pila de historial en una sola aplicación web móvil? (5)
Tengo una aplicación móvil de una sola página desarrollada con Backbone y Zepto.
Funciona correctamente con los botones atrás / adelante en el navegador.
Cuando el usuario navega hacia una página, el nuevo contenido se desliza desde la derecha a medida que el contenido anterior se desplaza hacia la izquierda (y fuera de la ventana gráfica). Quiero que ocurra lo mismo si el usuario presiona el botón "avanzar" del navegador. Todo esto funciona
Tengo una clase que agrego al elemento body navigate-back
que cambiará este comportamiento, por lo que cuando el usuario navega de regreso con el botón de retroceso del navegador, ve que el contenido vuelve a deslizarse desde la izquierda y el otro contenido se desliza hacia el derecho. Básicamente todo lo contrario de seguir adelante.
Necesito detectar si el usuario está navegando hacia atrás para poder invocar el comportamiento alternativo. He intentado implementar mi propia pila de historial, pero me he encontrado con muchos problemas en los que a veces marca un avance como navegación hacia atrás que arruina la señal visual. Ha descendido a un kludge de hacks ahora y probablemente solo me avergonzaría si lo publicara.
¿Cuál es la mejor manera de implementar mi propia pila de historial para poder detectar si el usuario está navegando hacia adelante / atrás en el contexto de una aplicación móvil Backbone de una sola página?
La rama v.6.x de Sammy.js (la que depende solo de los cambios hash) es un enfoque perfecto, más simple y más compatible con el navegador para el historial de seguimiento. Allí, la historia no se rastrea en absoluto, ya que Sammy solo busca el hashchange.
Confiar en "# / slide / 123" le permite admitir recargas de páginas duras y simplifica el trabajo
Despegue la última parte (número de diapositiva) en cada vista de página, presione en global. En una nueva ruta, vea si el número es más o menos de lo que está almacenado en global y realice la animación correcta (izquierda o derecha). Si global no está definido, no hay animación.
No sé sobre backbone.js 1 , pero he ayudado a desarrollar una aplicación móvil que tuvo que implementar exactamente este comportamiento en html5, así que debería poder darle un buen consejo:
En primer lugar, es bueno saber que existe la función history.pushState
. El gran problema es que es compatible con Android 2.3, pero no con Android 3 hasta Android 4.0.3 . Como kiranvj señala correctamente, esto puede resolverse utilizando la popular biblioteca history.js , que proporciona una solución de relleno para la falta de la funcionalidad del historial.
Ahora, llegando a su problema real, la forma en que implementé las animaciones de dirección del historial fue agregando datos a la función pushState
( history.pushState(data,title,url)
) con la cual identifiqué la posición lógica de la página. En mi aplicación, no solo estaba limitado a una barra horizontal, sino que en su caso usted mantendría un registro de la posición donde cualquier página nueva cargada obtiene una posición que es más alta que su página actual. P.ej
History.pushState({position:History.getState().data.position+1},"Your title","Your URL");
Luego, cuando se activa el evento window.onstatechange
o window.onanchorchange
, se observa si la posición es más alta o más baja que su página actual (por ejemplo, usando la función history.js History.getState()
que utilicé anteriormente) y dependiendo de esto, decida en qué dirección mover (más bajo está a la izquierda y más alto a la derecha), como lo ilustra la imagen a continuación:
También notará que ya asumí en la primera página que tiene {position:1}
, mientras que normalmente la primera página no tendrá información de estado. La forma en que esto se puede lograr es mediante el uso de history.replaceState
que reemplaza el estado vacío actual con un estado más informativo. Alternativamente, también puede verificar si hay un estado vacío en cualquiera de los eventos mencionados anteriormente y si está vacío, suponga que es el que está más a la izquierda ( {position:1}
).
Espero que esto ayude y si tiene alguna pregunta adicional no dude en preguntar.
Tenga en cuenta que esta respuesta supone que está utilizando history.js y que debería escuchar eventos ligeramente diferentes (como onpopstate
) y utilizar estructuras ligeramente diferentes ( history
lugar de History
) si desea construir su propia solución.
También es útil tener en cuenta que es posible construir esto con su propia matriz de colas que le da mucho más control, pero no funcionará en combinación con el botón Atrás del navegador. Este es un gran problema con los sitios del navegador, sin embargo, es mucho más fácil en caso de que esté construyendo una aplicación web cordova (aka phonegap ).
1 Acabo de leer sobre esto y parece que hace un poco de manejo de historia propio , lo que podría hacer que sea más complejo integrar la técnica descrita anteriormente.
Si está trabajando en una verdadera aplicación de una sola página, ¿por qué no configura una matriz para guardar urls de historial en una variable js (en lugar de basarse en algo como history.pushState
y su soporte)?
Cada vez que se navega por una nueva página, puede insertar su url en la matriz, siempre que se presione un botón "atrás", puede recuperar la url necesaria tan atrás como desee. Esto funcionará perfectamente siempre que descartes correctamente las URL cuando el usuario retrocede unos pocos pasos y luego navega hacia un nuevo enlace.
Nunca intenté implementar esto para usarlo en el historial de páginas, pero esto funcionó perfectamente para la lógica de deshacer y rehacer in-page.
Actualizar:
Después de más investigaciones, el enfoque anterior no funcionaría para una recarga de página, ya que sería una acción que ocurre fuera del manejo de historial disponible a través de JS. Todavía funcionaría para el seguimiento de las transiciones hacia adelante / atrás, pero se perderá ese historial al navegar hacia una URL externa a la aplicación o una actualización de página. La respuesta de David Mulder parece carecer de esta limitación al basarse en la historia del navegador que persiste fuera del alcance de la página.
Tuve el mismo problema al trabajar con Zepto en dispositivos móviles con una sola página: vistas múltiples.
Inicialmente utilicé html5 statechange y onhashchange. Todo tiene algunos problemas en uno u otro dispositivo móvil. Finalmente utilicé el plugin de historia Zepto desde aquí https://github.com/browserstate/history.js
De alguna manera resolvió la mayoría de los problemas. Pruébalo, será útil, maneja las características html4 y html5 siempre que sea posible.
Use esto en la aplicación móvil de una sola página, esto permitirá el historial y moverá al usuario hacia atrás.
function onBackKeyDown() {
history.go(-1);
navigator.app.backHistory();
}