Estoy usando jQuery Mobile, y tengo problemas para entender las diferencias entre los documentos clásicos preparados y los eventos de página de jQuery Mobile.
¿Cuál es la diferencia real?
Porque deberia
<!-- language: lang-js --> $(document).ready() { });
ser mejor que
$(document).on('pageinit') { });
¿Cuál es el orden de los eventos de la página cuando realiza la transición de una página a otra?
¿Cómo puedo enviar datos de una página a otra y es posible acceder a los datos de la página anterior?
javascript
jquery
html
jquery-mobile
cordova
usuario2001897
fuente
fuente
Respuestas:
Actualización de jQuery Mobile 1.4:
Mi artículo original estaba destinado a la forma antigua de manejo de páginas, básicamente todo antes de jQuery Mobile 1.4. La antigua forma de manejo ahora está en desuso y permanecerá activa hasta (incluido) jQuery Mobile 1.5, por lo que aún puede usar todo lo mencionado a continuación, al menos hasta el próximo año y jQuery Mobile 1.6.
Los eventos antiguos, incluido pageinit, ya no existen, se reemplazan con el widget pagecontainer . Pageinit se borra por completo y puede usar pagecreate en su lugar, ese evento se mantuvo igual y no se va a cambiar.
Si está interesado en una nueva forma de manejo de eventos de página, eche un vistazo aquí , en cualquier otro caso, no dude en continuar con este artículo. Debería leer esta respuesta incluso si está utilizando jQuery Mobile 1.4 +, va más allá de los eventos de la página, por lo que probablemente encontrará mucha información útil.
Contenido anterior:
Este artículo también se puede encontrar como parte de mi blog AQUÍ .
$(document).on('pageinit')
vs$(document).ready()
Lo primero que aprende en jQuery es llamar al código dentro de la
$(document).ready()
función para que todo se ejecute tan pronto como se cargue el DOM. Sin embargo, en jQuery Mobile , Ajax se usa para cargar el contenido de cada página en el DOM mientras navega. Debido a esto,$(document).ready()
se activará antes de que se cargue su primera página y cada código destinado a la manipulación de la página se ejecutará después de una actualización de la página. Esto puede ser un error muy sutil. En algunos sistemas puede parecer que funciona bien, pero en otros puede causar rarezas erráticas y difíciles de repetir.Sintaxis clásica de jQuery:
Para resolver este problema (y confía en mí, este es un problema), los desarrolladores de jQuery Mobile crearon eventos de página. En pocas palabras, los eventos de página son eventos desencadenados en un punto particular de ejecución de página. Uno de esos eventos de página es un evento pageinit y podemos usarlo así:
Podemos ir aún más lejos y usar una identificación de página en lugar del selector de documentos. Digamos que tenemos la página jQuery Mobile con un índice de identificación :
Para ejecutar código que solo estará disponible para la página de índice, podríamos usar esta sintaxis:
El evento Pageinit se ejecutará cada vez que se cargue la página y se muestre por primera vez. No se activará nuevamente a menos que la página se actualice manualmente o la carga de la página Ajax esté desactivada. En caso de que desee que el código se ejecute cada vez que visita una página, es mejor usar pagebeforeshow event.
Aquí hay un ejemplo de trabajo: http://jsfiddle.net/Gajotres/Q3Usv/ para demostrar este problema.
Pocas notas más sobre esta pregunta. No importa si está utilizando 1 html de múltiples páginas o paradigma de múltiples archivos HTML, se recomienda separar todo el manejo personalizado de su página JavaScript en un solo archivo JavaScript separado. Esto hará que su código sea mejor, pero tendrá una descripción general del código mucho mejor, especialmente al crear una aplicación jQuery Mobile .
También hay otro evento especial de jQuery Mobile y se llama mobileinit . Cuando se inicia jQuery Mobile , desencadena un evento mobileinit en el objeto del documento. Para anular la configuración predeterminada, vincúlela a mobileinit . Uno de los buenos ejemplos del uso de mobileinit es desactivar la carga de la página de Ajax o cambiar el comportamiento predeterminado del cargador de Ajax.
Orden de transición de eventos de página
Primero, todos los eventos se pueden encontrar aquí: http://api.jquerymobile.com/category/events/
Digamos que tenemos una página A y una página B, este es un orden de descarga / carga:
página B - página de evento antes de crear
página B - evento pagecreate
página B - evento pageinit
página A - página del evento antes
página A - página de eventosremove
página A - evento pagehide
página B - página del evento antes de mostrar
página B - evento páginashow
Para una mejor comprensión de los eventos de la página, lea esto:
pagebeforeload
,pageload
ypageloadfailed
se disparan cuando se carga una página externapagebeforechange
,pagechange
ypagechangefailed
son eventos de cambio de página. Estos eventos se activan cuando un usuario navega entre las páginas de las aplicaciones.pagebeforeshow
,pagebeforehide
,pageshow
Ypagehide
son eventos de transición de página. Estos eventos se disparan antes, durante y después de una transición y se nombran.pagebeforecreate
,pagecreate
ypageinit
son para la inicialización de la página.pageremove
puede ser despedido y luego manejado cuando una página se elimina del DOMEjemplo de carga de página jsFiddle: http://jsfiddle.net/Gajotres/QGnft/
Prevenir la transición de página
Si por alguna razón la transición de página necesita ser prevenida en alguna condición, se puede hacer con este código:
Este ejemplo funcionará en cualquier caso porque se activará al comienzo de cada transición de página y, lo que es más importante, evitará el cambio de página antes de que pueda ocurrir la transición de página.
Aquí hay un ejemplo de trabajo:
Prevenir múltiples eventos vinculantes / disparadores
jQuery Mobile
funciona de manera diferente a las aplicaciones web clásicas. Dependiendo de cómo logró vincular sus eventos cada vez que visita alguna página, los vinculará una y otra vez. Esto no es un error, es simplemente cómojQuery Mobile
maneja sus páginas. Por ejemplo, eche un vistazo a este fragmento de código:Ejemplo de trabajo de jsFiddle: http://jsfiddle.net/Gajotres/CCfL4/
Cada vez que visite la página #index click event estará vinculado al botón # test-button . Pruébelo moviéndose de la página 1 a la página 2 y viceversa varias veces. Hay pocas formas de prevenir este problema:
Solución 1
La mejor solución sería utilizar
pageinit
para vincular eventos. Si echa un vistazo a una documentación oficial, descubrirá quepageinit
se activará SOLO una vez, al igual que el documento listo, por lo que no hay forma de que los eventos se vuelvan a vincular nuevamente. Esta es la mejor solución porque no tiene gastos generales de procesamiento, como al eliminar eventos con el método off.Ejemplo de trabajo de jsFiddle: http://jsfiddle.net/Gajotres/AAFH8/
Esta solución de trabajo se basa en un ejemplo problemático anterior.
Solución 2
Eliminar evento antes de vincularlo:
Ejemplo de trabajo de jsFiddle: http://jsfiddle.net/Gajotres/K8YmG/
Solución 3
Use un selector de filtro jQuery, como este:
Debido a que el filtro de eventos no es parte del marco oficial de jQuery, se puede encontrar aquí: http://www.codenothing.com/archives/2009/event-filter/
En pocas palabras, si la velocidad es su principal preocupación, entonces la Solución 2 es mucho mejor que la Solución 1.
Solución 4
Una nueva, probablemente la más fácil de todas.
Ejemplo de trabajo de jsFiddle: http://jsfiddle.net/Gajotres/Yerv9/
Gracias al sholsinger para esta solución: http://sholsinger.com/archive/2011/08/prevent-jquery-live-handlers-from-firing-multiple-times/
peculiaridades del evento pageChange: se activa dos veces
A veces, el evento de cambio de página puede activarse dos veces y no tiene nada que ver con el problema mencionado anteriormente.
La razón por la cual el evento pagebeforechange ocurre dos veces se debe a la llamada recursiva en changePage cuando toPage no es un objeto DOM mejorado jQuery. Esta recursión es peligrosa, ya que el desarrollador puede cambiar el toPage dentro del evento. Si el desarrollador establece consistentemente toPage en una cadena, dentro del controlador de eventos pagebeforechange, independientemente de si se trata de un objeto o no, se producirá un bucle recursivo infinito. El evento de carga de página pasa la nueva página como la propiedad de la página del objeto de datos (Esto debe agregarse a la documentación, actualmente no figura en la lista). Por lo tanto, el evento de carga de página podría usarse para acceder a la página cargada.
En pocas palabras, esto está sucediendo porque está enviando parámetros adicionales a través de pageChange.
Ejemplo:
Para solucionar este problema, use cualquier evento de página que se encuentre en el orden de transición de eventos de página .
Tiempos de cambio de página
Como se mencionó, cuando cambia de una página de jQuery Mobile a otra, generalmente haciendo clic en un enlace a otra página de jQuery Mobile que ya existe en el DOM o llamando manualmente a $ .mobile.changePage, se producen varios eventos y acciones posteriores. En un nivel alto se producen las siguientes acciones:
Este es un punto de referencia de transición de página promedio:
Carga y procesamiento de la página: 3 ms
Mejora de página: 45 ms
Transición: 604 ms
Tiempo total: 670 ms
* Estos valores están en milisegundos.
Como puede ver, un evento de transición está consumiendo casi el 90% del tiempo de ejecución.
Manipulación de datos / parámetros entre transiciones de página
Es posible enviar un parámetro / s de una página a otra durante la transición de página. Se puede hacer de varias maneras.
Referencia: https://stackoverflow.com/a/13932240/1848600
Solución 1:
Puede pasar valores con changePage:
Y léelos así:
Ejemplo :
index.html
second.html
Solución 2:
O puede crear un objeto JavaScript persistente para un propósito de almacenamiento. Mientras Ajax se use para cargar la página (y la página no se vuelve a cargar de ninguna manera), ese objeto permanecerá activo.
Ejemplo: http://jsfiddle.net/Gajotres/9KKbx/
Solución 3:
También puede acceder a los datos de la página anterior de esta manera:
El objeto prevPage contiene una página anterior completa.
Solución 4:
Como última solución, tenemos una ingeniosa implementación HTML de localStorage. Solo funciona con navegadores HTML5 (incluidos los navegadores Android e iOS) pero todos los datos almacenados son persistentes a través de la actualización de la página.
Ejemplo: http://jsfiddle.net/Gajotres/J9NTr/
Probablemente la mejor solución, pero fallará en algunas versiones de iOS 5.X. Es un error bien conocido.
No use
.live()
/.bind()
/.delegate()
Olvidé mencionar (y tnx andleer por recordarme) usar on / off para la vinculación / desvinculación de eventos, live / die y bind / unbind están en desuso.
El método .live () de jQuery fue visto como un regalo del cielo cuando se introdujo en la API en la versión 1.3. En una aplicación típica de jQuery puede haber mucha manipulación DOM y puede ser muy tedioso enganchar y desenganchar a medida que los elementos van y vienen. El
.live()
método permitió enganchar un evento para la vida de la aplicación en función de su selector. Genial verdad? Incorrecto, el.live()
método es extremadamente lento. El.live()
método en realidad conecta sus eventos al objeto del documento, lo que significa que el evento debe burbujear desde el elemento que generó el evento hasta que llegue al documento. Esto puede llevar mucho tiempo.Ahora está en desuso. La gente del equipo de jQuery ya no recomienda su uso y yo tampoco. Aunque puede ser tedioso enganchar y desenganchar eventos, su código será mucho más rápido sin el
.live()
método que con él.En lugar de
.live()
usted debe usar.on()
..on()
es aproximadamente 2-3 veces más rápido que .live () . Eche un vistazo a este punto de referencia de enlace de eventos: http://jsperf.com/jquery-live-vs-delegate-vs-on/34 , todo estará claro a partir de ahí.Benchmarking:
Hay un excelente script hecho para la evaluación comparativa de eventos de la página jQuery Mobile . Se puede encontrar aquí: https://github.com/jquery/jquery-mobile/blob/master/tools/page-change-time.js . Pero antes de hacer nada con él, le aconsejo que elimine su
alert
sistema de notificación (cada "página de cambio" le mostrará estos datos deteniendo la aplicación) y que cambie para queconsole.log
funcione.Básicamente, este script registrará todos los eventos de su página y si lee este artículo detenidamente (descripciones de eventos de la página) sabrá cuánto tiempo pasó jQm de mejoras de la página, transiciones de la página ...
Notas finales
Siempre, y quiero decir, siempre leer la documentación oficial de jQuery Mobile . Por lo general, le proporcionará la información necesaria y, a diferencia de otra documentación, esta es bastante buena, con suficientes explicaciones y ejemplos de código.
Cambios:
fuente
$().live()
se depreció en jQuery 1.7 y se eliminó en 1.9, por lo que realmente debería ser parte de cualquier solución de jQuery Mobile. La versión actual de núcleo mínimo para jQM 1.7.pagecreate
El evento se activa solo una vez cuando se crea la página por primera vez. así que si vinculamos eventos de clic dentropagecreate
, no se disparará varias veces. Algo que descubrí mientras desarrollaba la aplicación. Pero no siempre podemos usarpagecreate
para vincular eventos, por lo que la solución que dio es la mejor. +1 dadoAlgunos de ustedes pueden encontrar esto útil. Simplemente copie y pegue en su página y obtendrá una secuencia en la que los eventos se activan en la consola de Chrome ( Ctrl+ Shift+ I).
No verá la descarga en la consola, ya que se dispara cuando se descarga la página (cuando se aleja de la página). Úselo así:
Y verás a qué me refiero.
fuente
Esta es la forma correcta:
Para ejecutar código que solo estará disponible para la página de índice, podríamos usar esta sintaxis:
fuente
La diferencia simple entre el documento listo y el evento de página en jQuery-mobile es que:
El evento de documento listo se usa para toda la página HTML,
Cuando hay un evento de página, utilícelo para manejar un evento de página en particular:
También puede usar el documento para manejar el evento pageinit:
fuente
Mientras usa .on (), es básicamente una consulta en vivo la que está usando.
Por otro lado, .ready (como en su caso) es una consulta estática. Mientras lo usa, puede actualizar dinámicamente los datos y no tiene que esperar a que se cargue la página. Simplemente puede pasar los valores a su base de datos (si es necesario) cuando se ingresa un valor particular.
El uso de consultas en vivo es común en los formularios donde ingresamos datos (cuenta o publicaciones o incluso comentarios).
fuente