Estou usando o jQuery Mobile e estou tendo problemas para entender as diferenças entre os eventos de páginas prontas para documentos clássicos e jQuery Mobile.
Qual é a diferença real?
Porque deveria
<!-- language: lang-js --> $(document).ready() { });
ser melhor que
$(document).on('pageinit') { });
Qual é a ordem dos eventos da página, quando você faz a transição de uma página para outra?
Como posso enviar dados de uma página para outra e é possível acessar dados da página anterior?
javascript
jquery
html
jquery-mobile
cordova
user2001897
fonte
fonte
Respostas:
Atualização do jQuery Mobile 1.4:
Meu artigo original foi projetado para o modo antigo de manipulação de páginas, basicamente tudo antes do jQuery Mobile 1.4. O modo antigo de manipulação agora está obsoleto e permanecerá ativo até (incluindo) o jQuery Mobile 1.5, para que você ainda possa usar tudo o que foi mencionado abaixo, pelo menos até o próximo ano e o jQuery Mobile 1.6.
Eventos antigos, incluindo o pageinit , não existem mais, são substituídos pelo widget de contêiner de paginação . O Pageinit é apagado completamente e você pode usar a criação de paginação , esse evento permaneceu o mesmo e não será alterado.
Se você estiver interessado em uma nova maneira de lidar com eventos da página, dê uma olhada aqui , em qualquer outro caso, sinta-se à vontade para continuar com este artigo. Você deve ler esta resposta, mesmo se estiver usando o jQuery Mobile 1.4 +, além dos eventos da página, provavelmente encontrará muitas informações úteis.
Conteúdo mais antigo:
Este artigo também pode ser encontrado como parte do meu blog AQUI .
$(document).on('pageinit')
vs$(document).ready()
A primeira coisa que você aprende no jQuery é chamar o código dentro da
$(document).ready()
função para que tudo seja executado assim que o DOM for carregado. No entanto, no jQuery Mobile , o Ajax é usado para carregar o conteúdo de cada página no DOM enquanto você navega. Por isso,$(document).ready()
será acionado antes que sua primeira página seja carregada e todos os códigos destinados à manipulação de páginas serão executados após uma atualização da página. Este pode ser um bug muito sutil. Em alguns sistemas, pode parecer que funciona bem, mas em outros pode causar estranheza irregular e difícil de repetir.Sintaxe clássica do jQuery:
Para resolver esse problema (e acredite, isso é um problema) Os desenvolvedores do jQuery Mobile criaram eventos de página. Em resumo, os eventos da página são eventos acionados em um determinado ponto de execução da página. Um desses eventos de página é um evento de pageinit e podemos usá-lo assim:
Podemos ir ainda mais longe e usar um ID da página em vez do seletor de documentos. Digamos que temos a página do jQuery Mobile com um índice de identificação :
Para executar o código que estará disponível apenas para a página de índice, poderíamos usar esta sintaxe:
O evento Pageinit será executado sempre que a página for carregada e mostrada pela primeira vez. Ele não será acionado novamente, a menos que a página seja atualizada manualmente ou o carregamento da página Ajax seja desativado. Caso você queira que o código seja executado toda vez que você visitar uma página, é melhor usar o evento pagebeforeshow .
Aqui está um exemplo de trabalho: http://jsfiddle.net/Gajotres/Q3Usv/ para demonstrar esse problema.
Mais algumas notas sobre esta questão. Independentemente de você estar usando um paradigma de várias páginas ou vários arquivos HTML, é recomendável separar toda a manipulação de sua página JavaScript personalizada em um único arquivo JavaScript separado. Isso fará com que seu código melhore, mas você terá uma visão geral muito melhor, especialmente ao criar um aplicativo jQuery Mobile .
Há também outro evento especial do jQuery Mobile , chamado mobileinit . Quando o jQuery Mobile é iniciado, ele dispara um evento mobileinit no objeto do documento. Para substituir as configurações padrão, vincule-as ao mobileinit . Um dos bons exemplos de uso do mobileinit é desativar o carregamento da página do Ajax ou alterar o comportamento padrão do carregador do Ajax.
Ordem de transição de eventos da página
Primeiro, todos os eventos podem ser encontrados aqui: http://api.jquerymobile.com/category/events/
Digamos que temos uma página A e uma página B, esta é uma ordem de descarregamento / carregamento:
página B - pagebeforecreate de eventos
página B - pagecreate de eventos
página B - evento pageinit
página A - pagebeforehide do evento
página A - pageremove do evento
página A - ocultar página do evento
página B - pagebeforeshow do evento
página B - pageshow de eventos
Para entender melhor os eventos da página, leia isto:
pagebeforeload
,pageload
Epageloadfailed
são disparados quando uma página externa é carregadapagebeforechange
,pagechange
Epagechangefailed
são eventos de mudança de página. Esses eventos são disparados quando um usuário está navegando entre as páginas nos aplicativos.pagebeforeshow
,pagebeforehide
,pageshow
Epagehide
são eventos de transição de página. Esses eventos são disparados antes, durante e após uma transição e são nomeados.pagebeforecreate
,pagecreate
Epageinit
são para a inicialização da página.pageremove
pode ser acionado e tratado quando uma página é removida do DOMExemplo de carregamento da página jsFiddle: http://jsfiddle.net/Gajotres/QGnft/
Impedir a transição da página
Se, por algum motivo, a transição da página precisar ser impedida sob alguma condição, isso poderá ser feito com este código:
Este exemplo funcionará em qualquer caso, pois será acionado no início de cada transição de página e o mais importante será impedir a alteração da página antes que ocorra a transição da página.
Aqui está um exemplo de trabalho:
Impedir a associação / acionamento de vários eventos
jQuery Mobile
funciona de maneira diferente dos aplicativos da web clássicos. Dependendo de como você conseguiu vincular seus eventos cada vez que você visita uma página, ele vincula os eventos repetidamente. Isso não é um erro, é simplesmente comojQuery Mobile
lida com suas páginas. Por exemplo, dê uma olhada neste snippet de código:Exemplo de jsFiddle de trabalho: http://jsfiddle.net/Gajotres/CCfL4/
Cada vez que você visitar a página #index click event será vinculado ao botão # test-button . Teste-o movendo da página 1 para a página 2 e retornando várias vezes. Existem algumas maneiras de evitar esse problema:
Solução 1
A melhor solução seria usar
pageinit
para vincular eventos. Se você der uma olhada em uma documentação oficial, descobrirá quepageinit
será acionada APENAS uma vez, assim como o documento está pronto, portanto não há como os eventos serem vinculados novamente. Esta é a melhor solução, porque você não possui sobrecarga de processamento, como ao remover eventos com o método off.Exemplo de jsFiddle de trabalho: http://jsfiddle.net/Gajotres/AAFH8/
Esta solução de trabalho é feita com base em um exemplo problemático anterior.
Solução 2
Remova o evento antes de ligá-lo:
Exemplo de jsFiddle de trabalho: http://jsfiddle.net/Gajotres/K8YmG/
Solução 3
Use um seletor de filtro jQuery, assim:
Como o filtro de eventos não faz parte da estrutura oficial do jQuery, ele pode ser encontrado aqui: http://www.codenothing.com/archives/2009/event-filter/
Em poucas palavras, se a velocidade é sua principal preocupação, a Solução 2 é muito melhor que a Solução 1.
Solução 4
Um novo, provavelmente o mais fácil de todos.
Exemplo de jsFiddle de trabalho: http://jsfiddle.net/Gajotres/Yerv9/
Tnx ao sholsinger para esta solução: http://sholsinger.com/archive/2011/08/prevent-jquery-live-handlers-from-firing-multiple-times/
peculiaridades do evento pageChange - acionando duas vezes
Às vezes, o evento de troca de paginação pode ser acionado duas vezes e não tem nada a ver com o problema mencionado anteriormente.
O motivo pelo qual o evento pagebeforechange ocorre duas vezes é devido à chamada recursiva no changePage quando toPage não é um objeto DOM aprimorado para jQuery. Essa recursão é perigosa, pois o desenvolvedor pode alterar o toPage no evento. Se o desenvolvedor definir consistentemente toPage como uma sequência, no manipulador de eventos pagebeforechange, independentemente de ser um objeto ou não, um loop recursivo infinito resultará. O evento pageload passa a nova página como propriedade da página do objeto de dados (isso deve ser adicionado à documentação, não está listado no momento). O evento pageload pode, portanto, ser usado para acessar a página carregada.
Em poucas palavras, isso está acontecendo porque você está enviando parâmetros adicionais através do pageChange.
Exemplo:
Para corrigir esse problema, use qualquer evento da página listado na ordem de transição de eventos da página .
Tempos de mudança de página
Como mencionado, quando você muda de uma página do jQuery Mobile para outra, geralmente clicando em um link para outra página do jQuery Mobile que já existe no DOM ou chamando manualmente $ .mobile.changePage, ocorrem vários eventos e ações subseqüentes. Em um nível alto, ocorrem as seguintes ações:
Este é um benchmark médio de transição de página:
Carregamento e processamento da página: 3 ms
Melhoria da página: 45 ms
Transição: 604 ms
Tempo total: 670 ms
* Esses valores estão em milissegundos.
Então, como você pode ver, um evento de transição está consumindo quase 90% do tempo de execução.
Manipulação de dados / parâmetros entre transições de página
É possível enviar um parâmetro / s de uma página para outra durante a transição da página. Isso pode ser feito de várias maneiras.
Referência: https://stackoverflow.com/a/13932240/1848600
Solução 1:
Você pode passar valores com changePage:
E leia-os assim:
Exemplo :
index.html
second.html
Solução 2:
Ou você pode criar um objeto JavaScript persistente para fins de armazenamento. Enquanto o Ajax for usado para carregar a página (e a página não for recarregada de forma alguma), esse objeto permanecerá ativo.
Exemplo: http://jsfiddle.net/Gajotres/9KKbx/
Solução 3:
Você também pode acessar os dados da página anterior, assim:
O objeto prevPage contém uma página anterior completa.
Solução 4:
Como última solução, temos uma implementação em HTML bacana do localStorage. Funciona apenas com navegadores HTML5 (incluindo navegadores Android e iOS), mas todos os dados armazenados são persistentes por meio da atualização da página.
Exemplo: http://jsfiddle.net/Gajotres/J9NTr/
Provavelmente a melhor solução, mas falhará em algumas versões do iOS 5.X. É um erro bem conhecido.
Não use
.live()
/.bind()
/.delegate()
Eu esqueci de mencionar (e tnx andleer para me lembrar) o uso on / off para vinculação / desativação de eventos, viver / morrer e vincular / desativar são preteridos.
O método .live () do jQuery foi visto como uma dádiva de Deus quando foi introduzido na API na versão 1.3. Em um aplicativo jQuery típico, pode haver muita manipulação de DOM e pode ser muito entediante enganchar e desatar os elementos à medida que os elementos vão e vêm. O
.live()
método tornou possível ligar um evento para a vida útil do aplicativo com base em seu seletor. Ótimo, certo? Errado, o.live()
método é extremamente lento. O.live()
método realmente conecta seus eventos ao objeto do documento, o que significa que o evento deve aparecer do elemento que gerou o evento até chegar ao documento. Isso pode ser incrivelmente demorado.Agora está obsoleto. As pessoas da equipe do jQuery não recomendam mais o seu uso, nem eu. Mesmo que possa ser entediante ligar e desconectar eventos, seu código será muito mais rápido sem o
.live()
método do que com ele.Em vez de
.live()
você deve usar.on()
..on()
é cerca de 2-3x mais rápido que .live () . Dê uma olhada neste benchmark de associação de eventos: http://jsperf.com/jquery-live-vs-delegate-vs-on/34 , tudo ficará claro a partir daí.Avaliação comparativa:
Existe um excelente script feito para o benchmarking de eventos da página do jQuery Mobile . Pode ser encontrado aqui: https://github.com/jquery/jquery-mobile/blob/master/tools/page-change-time.js . Mas antes de fazer qualquer coisa com ele, aconselho a remover o
alert
sistema de notificação (cada “página de alteração” mostrará esses dados interrompendo o aplicativo) e altere-o paraconsole.log
funcionar.Basicamente, esse script registrará todos os eventos da sua página e, se você ler este artigo atentamente (descrições dos eventos da página), saberá quanto tempo o jQm gastou em aprimoramentos e transições de página.
Notas finais
Sempre, quero dizer, sempre leia a documentação oficial do jQuery Mobile . Geralmente, ele fornece as informações necessárias e, ao contrário de outras documentações, essa é bastante boa, com explicações e exemplos de código suficientes.
Alterar:
fonte
$().live()
foi depreciado no jQuery 1.7 e removido no 1.9; portanto, ele realmente deve fazer parte de qualquer solução do jQuery Mobile. A versão principal mínima atual para o jQM 1.7.pagecreate
O evento é acionado apenas uma vez quando a página é criada. portanto, se vincularmos os eventos de clique,pagecreate
ele não será acionado várias vezes. Algo que descobri ao desenvolver o aplicativo. Mas nem sempre podemos usarpagecreate
para vincular eventos, portanto a solução que você deu é a melhor. 1 dadoAlguns de vocês podem achar isso útil. Basta copiar e colar na sua página e você obterá uma sequência na qual os eventos são disparados no console do Chrome ( Ctrl+ Shift+ I).
Você não verá descarregar no console, pois é acionado quando a página está sendo descarregada (quando você se afasta da página). Use-o assim:
E você verá o que quero dizer.
fonte
Esta é a maneira correta:
Para executar o código que estará disponível apenas para a página de índice, podemos usar esta sintaxe:
fonte
A diferença simples entre o documento pronto e o evento da página no jQuery-mobile é que:
O evento pronto para o documento é usado para toda a página HTML,
Quando houver um evento de página, use para manipular um evento de página específico:
Você também pode usar o documento para manipular o evento pageinit:
fonte
Enquanto você usa .on (), é basicamente uma consulta ao vivo que você está usando.
Por outro lado, .ready (como no seu caso) é uma consulta estática. Ao usá-lo, você pode atualizar dados dinamicamente e não precisa esperar a página carregar. Você pode simplesmente passar os valores para o seu banco de dados (se necessário) quando um valor específico for inserido.
O uso de consultas ativas é comum em formulários nos quais inserimos dados (conta ou postagens ou até mesmo comentários).
fonte