Eu encontrei um problema no meu aplicativo Rails 4 enquanto tentava organizar arquivos JS "da maneira dos trilhos". Eles foram anteriormente espalhados por diferentes pontos de vista. Organizei-os em arquivos separados e os compilei com o pipeline de ativos. No entanto, acabei de saber que o evento "pronto" do jQuery não é acionado nos cliques subseqüentes quando o turbo-link está ativado. A primeira vez que você carrega uma página, ela funciona. Mas quando você clica em um link, qualquer coisa dentro do ready( function($) {
arquivo não é executada (porque a página não é carregada novamente). Boa explicação: aqui .
Portanto, minha pergunta é: Qual é a maneira correta de garantir que os eventos jQuery funcionem corretamente enquanto os links turbo estiverem ativados? Você agrupa os scripts em um ouvinte específico do Rails? Ou talvez os trilhos tenham alguma mágica que o torna desnecessário? Os documentos são um pouco vagos sobre como isso deve funcionar, especialmente no que diz respeito ao carregamento de vários arquivos por meio do manifesto (s) como application.js.
fonte
var ready = function() { ... } $(document).ready(ready) $(document).on('page:load', ready)
existe alguma preocupação com os dois.ready
e'page:load'
com o gatilho?ready
evento será acionado. Se for uma carga de turbolinks, apenas opage:load
evento será disparado. É impossível para ambosready
epage:load
ser demitido na mesma página.page:load
eready
incluindo uma cadeia de caracteres separada por espaço para o primeiro argumet.$(document).on('page:load ready', ready);
O segundo argumento é simplesmente uma função, que é nomeadaready
, seguindo o exemplo desta resposta.Acabei de aprender de outra opção para resolver esse problema. Se você carregar a
jquery-turbolinks
gema, ela vinculará os eventos Rails Turbolinks aosdocument.ready
eventos, para que você possa escrever seu jQuery da maneira usual. Você acabou de adicionarjquery.turbolinks
logo depoisjquery
no arquivo de manifesto js (por padrãoapplication.js
:).fonte
//= require jquery.turbolinks
ao manifesto (por exemplo, application.js).Recentemente, encontrei a maneira mais limpa e fácil de entender:
OU
EDIT
Se você delegou eventos vinculados a
document
, certifique-se de anexá-los fora daready
função, caso contrário eles serão recuperados em todos ospage:load
eventos (fazendo com que as mesmas funções sejam executadas várias vezes). Por exemplo, se você tiver chamadas como esta:Tire-os da
ready
função, assim:Eventos delegados vinculados ao
document
não precisam ser vinculados aoready
evento.fonte
ready()
função separada . Votos positivos de bônus para a explicação de vincular eventos delegados fora daready
função.$(document).on( "ready", handler ), deprecated as of jQuery 1.8.
jQuery / Prontoready
parte é invalidada usando a gema?Encontrei isso na documentação do Rails 4 , semelhante à solução do DemoZluk, mas um pouco menor:
OU
Se você tiver scripts externos que chamam
$(document).ready()
ou se não puder se preocupar em reescrever todo o JavaScript existente, essa gema permitirá que você continue usando o$(document).ready()
TurboLinks: https://github.com/kossnocorp/jquery.turbolinksfonte
De acordo com as novas guias de trilhos , a maneira correta é fazer o seguinte:
ou, em coffeescript:
Não ouça o evento
$(document).ready
e apenas um evento será acionado. Sem surpresas, sem necessidade de usar a jquery.turbolinks .Isso funciona com os trilhos 4.2 e acima, não apenas com os trilhos 5.
fonte
"turbolinks:load"
evento funciona no Rails 4.2? Oturbolinks:
prefixo do evento foi introduzido no New Turbolinks e não é usado no Rails 4.2 IIRC, que usa o Turbolinks Classic . Considere tentar"page:change"
se"turbolinks:load"
não funcionar no seu aplicativo anterior ao Rails 5. Veja guias.rubyonrails.org/v4.2.7/…page:change
ou atualize os turbolinks. Também encontrado isso, pode ser relevante para alguns, onde turbolinks traduz eventos para os antigos nomes de evento: github.com/turbolinks/turbolinks/blob/v5.0.0/src/turbolinks/...alert "page has loaded!"
necessidade de ser recuado para ser realmente executada pela função de retorno de chamada?NOTA: Consulte a resposta do @ SDP para obter uma solução limpa e integrada
Corrigi-o da seguinte maneira:
inclua application.js antes que os outros arquivos js dependentes do aplicativo sejam incluídos, alterando a ordem de inclusão da seguinte maneira:
Defina uma função global que lida com a ligação em
application.js
Agora você pode vincular coisas como:
fonte
ready
evento, isso significa que você pode usar o modo "padrão" de inicialização:$(document).ready(function() { /* do your init here */});
. Seu código de inicialização deve ser chamado quando a página completa é carregada (-> sem turbolinks) e seu código de inicialização deve ser executado novamente quando você carrega uma página através de turbolinks. Se você deseja executar algum código SOMENTE quando um turbolink tiver sido usado:$(document).on('page:load', function() { /* init only for turbolinks */});
Nenhuma das opções acima funciona para mim, resolvi isso não usando $ (document) .ready do jQuery, mas use addEventListener.
fonte
fonte
turbolinks:load
no primeiro carregamento da página, Safari não ea maneira hacky para corrigi-lo (provocandoturbolinks:load
onapplication.js
), obviamente, quebra Chrome (que dispara duas vezes com isso). Essa é a resposta correta. Definitivamente vá com os 2 eventosready
eturbolinks:load
.Você tem que usar:
do turbolinks doc .
fonte
Ou use o
ou use a função .on do jQuery para obter o mesmo efeito
veja aqui para mais detalhes: http://srbiv.github.io/2013/04/06/rails-4-my-first-run-in-with-turbolinks.html
fonte
Em vez de usar uma variável para salvar a função "ready" e vinculá-la aos eventos, convém acionar o
ready
evento sempre quepage:load
acionar.fonte
Aqui está o que eu fiz para garantir que as coisas não sejam executadas duas vezes:
Acho que o uso da
jquery-turbolinks
gema ou combinação$(document).ready
e /$(document).on("page:load")
ou$(document).on("page:change")
por si só se comporta inesperadamente - especialmente se você estiver em desenvolvimento.fonte
$(document).off
bit da função anônima "page: change" acima, ele obviamente alertará quando eu chegar a essa página. Mas pelo menos no desenvolvimento executando o WEBrick, ele também alertará quando eu clicar em um link para outra página. Pior ainda, ele alerta duas vezes quando eu clico em um link para a página original.Encontrei o seguinte artigo que funcionou muito bem para mim e detalha o uso do seguinte:
fonte
Imaginei que deixaria isso aqui para os que estão atualizando para o Turbolinks 5 : a maneira mais fácil de corrigir seu código é:
para:
Referência: https://github.com/turbolinks/turbolinks/issues/9#issuecomment-184717346
fonte
fonte
turbolinks:load
evento é acionado para o carregamento inicial da página, bem como após os links a seguir. Se você anexar um evento aoready
evento padrão e aoturbolinks:load
evento, ele será acionado duas vezes quando você visitar uma página pela primeira vez.ready
dispara duas vezes em carregamentos de páginas subsequentes. Altere ou remova-o.Testado tantas soluções finalmente chegou a isso. Muitos desses códigos definitivamente não são chamados duas vezes.
fonte
Eu costumo fazer o seguinte nos meus 4 projetos rails:
No
application.js
No restante dos arquivos .js, em vez de usar
$(function (){})
eu chamoonInit(function(){})
fonte
Primeiro, instale a
jquery-turbolinks
gema. E não esqueça de mover os arquivos Javascript incluídos do final do seu corpoapplication.html.erb
para o dele<head>
.Conforme descrito aqui , se você tiver colocado o link javascript do aplicativo no rodapé por motivos de otimização de velocidade, será necessário movê-lo para a tag para que seja carregado antes do conteúdo da tag. Esta solução funcionou para mim.
fonte
Descobri minhas funções dobradas ao usar uma função para
ready
e,turbolinks:load
por isso, usei,Dessa forma, suas funções não dobram se turbolinks forem suportados!
fonte