web-dev-qa-db-fra.com

Rails 4 turbo-link empêche les scripts jQuery de fonctionner

Je construis une application Rails 4 et j'ai quelques fichiers js dispersés que j'essaie d'inclure "la manière Rails"). J'ai déplacé jquery plugins dans/vendor/assets/javascripts et j'ai mis à jour le manifeste (application.js) pour en avoir besoin. Lorsque je charge les pages localement, je vois qu'elles apparaissent correctement.

Cependant, je reçois un comportement incohérent de l'un des scripts qui sont compilés. J'ai un fichier js spécifique au contrôleur appelé projects.js qui est référencé dans l'application.js via l'utilisation de require_tree .:

//= require jquery
//= require jquery_ujs
//= require turbolinks
//= require bootstrap.min
//= require jquery.form.min
//= require_tree .

Je vois que le fichier est inclus correctement, et cela fonctionne ... la moitié du temps. L'autre moitié du temps, le contenu de projects.js ne semble rien faire (ce sont principalement des animations jquery et quelques requêtes ajax). Lorsque cela ne fonctionne pas, je clique sur les boutons plusieurs fois, rien ne se passera, puis je lancerai cette erreur:

Uncaught TypeError: Cannot read property 'position' of null 
turbolinks.js?body=1:75

Cela ne s'est jamais produit lorsque les scripts étaient dans les vues individuelles (dans le mauvais sens), donc je suis assez certain que le problème ne vient pas de mon code javascript. Un autre détail potentiellement pertinent est que le contenu de projects.js est enveloppé dans une $(document).ready(function(){. De plus, je teste en mode développement afin que les javascripts et les css ne soient pas combinés par le pipeline d'actifs.

Une idée de ce qui se passe ici? Je suis nouveau à Rails mais j'ai fait de mon mieux pour suivre toutes les conventions.

Mettre à jour!

Il est prévisible lorsque mes scripts de projet ne fonctionnent pas. Le premier chargement de page fonctionne à chaque fois. Ensuite, je clique sur un lien vers une nouvelle page qui utilise mes comportements project.js et la deuxième page ne fonctionne jamais. Je clique plusieurs fois et finalement jette l'erreur ci-dessus. Je ne sais toujours pas pourquoi, mais je soupçonne que cela est lié à la liaison turbo.

47
emersonthis

$(document).ready(function(){ ne fonctionne pas vraiment avec Turbolinks. Turbolinks :

... accélère les liens suivants dans votre application Web. Au lieu de laisser le navigateur recompiler le JavaScript et le CSS entre chaque changement de page, il maintient l'instance de page actuelle en vie et ne remplace que le corps et le titre dans l'en-tête.

Ainsi, la page n'est chargée qu'une seule fois, puis les pièces sont remplacées au besoin. Étant donné que la page n'est chargée qu'une seule fois, vos rappels $(document).ready() ne sont déclenchés que lorsque le site est initialement visité, vous n'obtiendrez pas plus d'événements prêts pour le document lorsque vous changez de page car Turbolinks ne change pas réellement de page. Du manuel fin :

Avec Turbolinks, les pages changeront sans rechargement complet, vous ne pouvez donc pas compter sur DOMContentLoaded ou jQuery.ready() pour déclencher votre code. Au lieu de cela, Turbolinks déclenche des événements sur le document pour fournir des crochets dans le cycle de vie de la page.

Vous voudrez probablement écouter l'un des événements Turbolinks à la place:

  • page:change la page a été analysée et modifiée pour la nouvelle version et sur DOMContentLoaded
  • [...]
  • page:load est renvoyé à la fin du processus de chargement.

page:change est généralement ce que vous recherchez car il est déclenché lors du chargement d'une nouvelle page et de la restauration d'une page à partir du cache de page Turbolinks.

Vous voudrez peut-être désactiver Turbolinks jusqu'à ce que vous ayez eu le temps de revoir tous votre JavaScript et que vous ayez effectué un balayage QA complet. Vous devez également tester la vitesse de votre site pour voir s'il vaut la peine d'être utilisé.

Une autre option serait d'utiliser jquery.turbolinks pour corriger les choses pour vous. Je ne l'ai pas utilisé mais d'autres personnes l'utilisent à bon escient.

43
mu is too short

Une solution à cela est déjà disponible à ce railscast

Voici un exemple (celui que j'aime utiliser).

ready = ->
  # ..... your js

$(document).ready(ready)
$(document).on('page:load', ready)

Il y a aussi un joya qui résout ce problème d'une manière qui vous permet de continuer à le faire à l'ancienne. Ça marche vraiment bien :)

28

Je me rends compte que cette réponse est REAAAAAAALLLLLLLYYYYY en retard ... mais j'ai pensé que je l'ajouterais.

Je viens d'avoir ce problème la semaine dernière .. Tout en essayant de faire fonctionner la Fondation ..

J'ai d'abord ajouté:

gem 'jquery-turbolinks'

Puis placé dans application.js ainsi:

//= require jquery.turbolinks
//= require jquery_ujs
//= require turbolinks
//= require_tree .

puis j'ai ajouté ceci juste en dessous:

$(document).on('turbolinks:load', function() {

});

et tout a fonctionné pour moi. J'espère que cela t'aides!

1
Shawn Wilson