J'ai rencontré un problème dans mon application Rails 4 en essayant d'organiser les fichiers JS "à la manière des rails". Ils étaient auparavant dispersés dans différentes vues. Je les ai organisés dans des fichiers séparés et les compile avec le pipeline d'actifs. Cependant, je viens d'apprendre que l'événement "prêt" de jQuery ne se déclenche pas lors des clics suivants lorsque la liaison est activée. La première fois que vous chargez une page, cela fonctionne. Mais lorsque vous cliquez sur un lien, rien à l'intérieur de ready( function($) {
ne sera exécuté (car la page ne se charge pas à nouveau). Bonne explication: ici .
Ma question est donc la suivante: quelle est la bonne façon de s'assurer que les événements jQuery fonctionnent correctement lorsque les turbo-liens sont activés? Enveloppez-vous les scripts dans un écouteur spécifique à Rails? Ou peut-être que les rails ont une magie qui les rend inutiles? Les documents sont un peu vagues sur la façon dont cela devrait fonctionner, en particulier en ce qui concerne le chargement de plusieurs fichiers via le (s) manifeste (s) comme application.js.
la source
var ready = function() { ... } $(document).ready(ready) $(document).on('page:load', ready)
y a-t-il une préoccupation pour les deux.ready
et pour'page:load'
être déclenché?ready
événement est déclenché. S'il s'agit d'une charge de turboliens, seul l'page:load
événement est déclenché. Il est impossible pour les deuxready
etpage:load
d'être renvoyé sur la même page.page:load
etready
en incluant une chaîne séparée par des espaces pour le premier argument.$(document).on('page:load ready', ready);
Le deuxième argument est simplement une fonction, qui se trouve être nomméeready
, en suivant l'exemple de cette réponse.Je viens d'apprendre une autre option pour résoudre ce problème. Si vous chargez la
jquery-turbolinks
gemme, elle liera les événements Rails Turbolinks auxdocument.ready
événements afin que vous puissiez écrire votre jQuery de la manière habituelle. Vous venez d'ajouterjquery.turbolinks
juste aprèsjquery
dans le fichier manifeste js (par défaut:)application.js
.la source
//= require jquery.turbolinks
au manifeste (par exemple application.js).Récemment, j'ai trouvé le moyen le plus propre et le plus facile à comprendre:
OU
EDIT
Si vous avez des événements délégués liés à l '
document
, assurez-vous de les attacher en dehors de laready
fonction, sinon ils seront rebondis sur chaquepage:load
événement (provoquant l'exécution des mêmes fonctions plusieurs fois). Par exemple, si vous avez des appels comme celui-ci:Retirez-les de la
ready
fonction, comme ceci:Les événements délégués liés au
document
ne doivent pas nécessairement être liés à l'ready
événement.la source
ready()
fonction distincte . Bonus de votes positifs pour l'explication des événements délégués contraignants en dehors de laready
fonction.$(document).on( "ready", handler ), deprecated as of jQuery 1.8.
jquery / readyready
portion est-elle invalide en utilisant la gemme?Trouvé dans la documentation de Rails 4 , similaire à la solution de DemoZluk mais légèrement plus courte:
OU
Si vous avez des scripts externes qui appellent
$(document).ready()
ou si vous ne pouvez pas être dérangé par la réécriture de tout votre JavaScript existant, ce joyau vous permet de continuer à utiliser$(document).ready()
avec TurboLinks: https://github.com/kossnocorp/jquery.turbolinksla source
Selon les nouveaux guides de rails , la bonne façon est de procéder comme suit:
ou, en coffeescript:
N'écoutez pas l'événement
$(document).ready
et un seul événement sera déclenché. Pas de surprise, pas besoin d'utiliser le joyau jquery.turbolinks .Cela fonctionne avec les rails 4.2 et supérieurs, pas seulement les rails 5.
la source
"turbolinks:load"
événement fonctionne dans Rails 4.2? Leturbolinks:
préfixe d'événement a été introduit dans les nouveaux Turbolinks et n'est pas utilisé dans Rails 4.2 IIRC qui utilise Turbolinks Classic . Pensez à essayer"page:change"
si"turbolinks:load"
cela ne fonctionne pas sur votre application pré-Rails 5. Voir guides.rubyonrails.org/v4.2.7/…page:change
ou mettez à niveau les turboliens. Également trouvé cela, peut être pertinent pour certains, où turbolinks traduit les événements en anciens noms d'événement: github.com/turbolinks/turbolinks/blob/v5.0.0/src/turbolinks/…alert "page has loaded!"
besoin doit-il être mis en retrait pour être réellement exécuté par la fonction de rappel?REMARQUE: Voir la réponse de @ SDP pour une solution propre et intégrée
Je l'ai corrigé comme suit:
assurez-vous d'inclure application.js avant que les autres fichiers js dépendants de l'application ne soient inclus en modifiant l'ordre d'inclusion comme suit:
Définissez une fonction globale qui gère la liaison dans
application.js
Maintenant, vous pouvez lier des trucs comme:
la source
ready
événement, cela signifie que vous pouvez utiliser comme « standard » d'initialisation:$(document).ready(function() { /* do your init here */});
. Votre code init doit être appelé lorsque la page complète est chargée (-> sans turbolinks) et votre code init doit être exécuté à nouveau lorsque vous chargez une page via turbolinks. Si vous voulez exécuter du code UNIQUEMENT quand un turbolink a été utilisé:$(document).on('page:load', function() { /* init only for turbolinks */});
Rien de ce qui précède ne fonctionne pour moi, j'ai résolu cela en n'utilisant pas $ (document) .ready de jQuery, mais en utilisant addEventListener à la place.
la source
la source
turbolinks:load
sur la première page de chargement, Safari ne fonctionne pas et la façon hacky pour y remédier (déclenchementturbolinks:load
surapplication.js
) brise évidemment Chrome (qui se déclenche deux fois avec cela). Ceci est la bonne réponse. Allez-y avec les 2 événementsready
etturbolinks:load
.Vous devez utiliser:
de turbolinks doc .
la source
Soit utiliser le
ou utilisez la fonction .on de jQuery pour obtenir le même effet
voir ici pour plus de détails: http://srbiv.github.io/2013/04/06/rails-4-my-first-run-in-with-turbolinks.html
la source
Au lieu d'utiliser une variable pour enregistrer la fonction "prête" et la lier aux événements, vous souhaiterez peut-être déclencher l'
ready
événement chaque fois qu'il sepage:load
déclenche.la source
Voici ce que j'ai fait pour m'assurer que les choses ne sont pas exécutées deux fois:
Je trouve que l'utilisation de la
jquery-turbolinks
gemme ou la combinaison$(document).ready
et /$(document).on("page:load")
ou l'utilisation$(document).on("page:change")
par elle-même se comporte de manière inattendue - surtout si vous êtes en développement.la source
$(document).off
bit dans cette fonction anonyme "page: change" au-dessus, il sera évidemment alerté quand j'arriverai à cette page. Mais au moins dans le développement sous WEBrick, il sera également alerté lorsque je clique sur un lien vers une autre page. Événement pire, il alerte deux fois lorsque je clique ensuite sur un lien vers la page d'origine.J'ai trouvé l' article suivant qui a très bien fonctionné pour moi et détaille l'utilisation des éléments suivants:
la source
Je pensais que je laisserais cela ici pour ceux qui passent à Turbolinks 5 : la façon la plus simple de corriger votre code est de:
à:
Référence: https://github.com/turbolinks/turbolinks/issues/9#issuecomment-184717346
la source
la source
turbolinks:load
événement se déclenche pour le chargement initial de la page ainsi qu'après les liens suivants. Si vous attachez un événement à la fois à l'ready
événement standard et à l'turbolinks:load
événement, il se déclenchera deux fois lors de votre première visite sur une page.ready
se déclenche deux fois lors des chargements de page suivants. Veuillez le modifier ou le supprimer.Tester tant de solutions est finalement arrivé à cela. Ce nombre de votre code n'est certainement pas appelé deux fois.
la source
Je fais généralement ce qui suit pour mes projets rails 4:
Dans
application.js
Ensuite, dans le reste des fichiers .js, au lieu d'utiliser
$(function (){})
j'appelleonInit(function(){})
la source
Tout d'abord, installez
jquery-turbolinks
gem. Et puis, n'oubliez pas de déplacer vos fichiers Javascript inclus de la fin du corps de votreapplication.html.erb
vers son<head>
.Comme décrit ici , si vous avez mis le lien javascript de l'application dans le pied de page pour des raisons d'optimisation de la vitesse, vous devrez le déplacer dans la balise afin qu'il se charge avant le contenu de la balise. Cette solution a fonctionné pour moi.
la source
J'ai trouvé mes fonctions doublées lors de l'utilisation d'une fonction pour
ready
etturbolinks:load
j'ai donc utilisé,De cette façon, vos fonctions ne doublent pas si les turboliens sont pris en charge!
la source