it-swarm.com.de

Rails 4: Verwendung von $ (document) .ready () mit Turbolinks

Ich bin auf ein Problem in meiner Rails 4-App gestoßen, als ich versucht habe, JS-Dateien "auf die Rails Weise" zu organisieren. Sie waren zuvor auf verschiedene Ansichten verteilt. Ich habe sie in separate Dateien organisiert und mit der Assets-Pipeline kompiliert. Ich habe jedoch gerade erfahren, dass das "ready" -Ereignis von jQuery bei nachfolgenden Klicks nicht ausgelöst wird, wenn die Turbo-Verknüpfung aktiviert ist. Wenn Sie zum ersten Mal eine Seite laden, funktioniert es. Wenn Sie jedoch auf einen Link klicken, wird nichts in ready( function($) { ausgeführt (da die Seite nicht erneut geladen wird). Gute Erklärung: hier .

Meine Frage lautet also: Wie kann ich sicherstellen, dass jQuery-Ereignisse ordnungsgemäß funktionieren, während Turbolinks aktiv sind? Packen Sie die Skripte in einen Rails-spezifischen Listener? Oder vielleicht hat Rails etwas Magie, die es unnötig macht? Die Dokumentation ist ein wenig vage, wie dies funktionieren soll, insbesondere in Bezug auf das Laden mehrerer Dateien über das Manifest (die Manifeste) wie application.js.

416
emersonthis

Ich habe gerade von einer anderen Möglichkeit zur Lösung dieses Problems erfahren. Wenn Sie den Edelstein jquery-turbolinks laden, werden die Ereignisse Rails Turbolinks an die Ereignisse document.ready gebunden, sodass Sie Ihre jQuery wie gewohnt schreiben können. Sie fügen einfach jquery.turbolinks direkt nach jquery in die js-Manifestdatei ein (standardmäßig: application.js).

235
emersonthis

Folgendes mache ich ... CoffeeScript:

ready = ->

  ...your coffeescript goes here...

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

die letzte Zeile wartet auf das Laden der Seite, was Turbolinks auslösen.

Bearbeiten ... Hinzufügen einer Javascript-Version (auf Anfrage):

var ready;
ready = function() {

  ...your javascript goes here...

};

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

Edit 2 ... Für Rails 5 (Turbolinks 5) page:load wird turbolinks:load und wird sogar beim ersten Laden abgefeuert. Wir können also einfach Folgendes tun:

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

  ...your javascript goes here...

});
549
Meltemi

Kürzlich fand ich die sauberste und verständlichste Art, damit umzugehen:

$(document).on 'ready page:load', ->
  # Actions to do

ODER

$(document).on('ready page:load', function () {
  // Actions to do
});

EDIT
Wenn Sie delegierte Ereignisse an document gebunden haben, stellen Sie sicher, dass Sie sie außerhalb der ready -Funktion anhängen, da sie andernfalls bei jedem page:load -Ereignis (führt dazu, dass dieselben Funktionen mehrmals ausgeführt werden). Wenn Sie beispielsweise folgende Anrufe haben:

$(document).on 'ready page:load', ->
  ...
  $(document).on 'click', '.button', ->
    ...
  ...

Nehmen Sie sie wie folgt aus der Funktion ready heraus:

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

$(document).on 'click', '.button', ->
  ...

An document gebundene delegierte Ereignisse müssen nicht an das ready -Ereignis gebunden sein.

201
Artyom Tsoy

Gefunden in der Rails 4-Dokumentation , ähnlich der DemoZluk-Lösung, aber etwas kürzer:

$(document).on 'page:change', ->
  # Actions to do

OR

$(document).on('page:change', function () {
  // Actions to do
});

Wenn Sie externe Skripte haben, die $(document).ready() aufrufen, oder wenn Sie nicht die Mühe haben, Ihr gesamtes vorhandenes JavaScript neu zu schreiben, können Sie mit diesem Juwel weiterhin $(document).ready() mit TurboLinks verwenden: https: // github.com/kossnocorp/jquery.turbolinks

91
migu

Gemäß dem neuen Schienenführungen ist die korrekte Vorgehensweise wie folgt:

$(document).on('turbolinks:load', function() {
   console.log('(document).turbolinks:load')
});

oder im Kaffeeskript:

$(document).on "turbolinks:load", ->
alert "page has loaded!"

Hören Sie nicht auf das Ereignis $(document).ready und es wird nur ein Ereignis ausgelöst. Keine Überraschungen, keine Notwendigkeit, das Juwel jquery.turbolinks zu verwenden.

Dies funktioniert mit Rails 4.2 und höher, nicht nur mit Rails 5.

78
vedant

HINWEIS: Eine saubere, integrierte Lösung finden Sie in der Antwort von @ SDP

Ich habe es wie folgt behoben:

stellen Sie sicher, dass Sie application.js einschließen, bevor die anderen app-abhängigen js-Dateien eingeschlossen werden, indem Sie die Einschlussreihenfolge wie folgt ändern:

// in application.js - make sure `require_self` comes before `require_tree .`
//= require_self
//= require_tree .

Definieren Sie eine globale Funktion, die die Bindung in application.js verarbeitet.

// application.js
window.onLoad = function(callback) {
  // binds ready event and turbolink page:load event
  $(document).ready(callback);
  $(document).on('page:load',callback);
};

Jetzt können Sie Sachen binden wie:

// in coffee script:
onLoad ->
  $('a.clickable').click => 
    alert('link clicked!');

// equivalent in javascript:
onLoad(function() {
  $('a.clickable').click(function() {
    alert('link clicked');
});
10
sled

Keines der oben genannten Probleme funktioniert für mich. Ich habe dieses Problem gelöst, indem ich nicht jQueries $ (document) .ready verwendet habe, sondern stattdessen addEventListener.

document.addEventListener("turbolinks:load", function() {
  // do something
});
8
RockL
$(document).on 'ready turbolinks:load', ->
  console.log '(document).turbolinks:load'
6
Sukeerthi Adiga

Sie müssen verwenden:

document.addEventListener("turbolinks:load", function() {
  // your code here
})

von turbolinks doc .

Verwenden Sie entweder die

$(document).on "page:load", attachRatingHandler

oder verwenden Sie die .on-Funktion von jQuery, um den gleichen Effekt zu erzielen

$(document).on 'click', 'span.star', attachRatingHandler

weitere Informationen finden Sie hier: http://srbiv.github.io/2013/04/06/Rails-4-my-first-run-in-with-turbolinks.html

3
derekyau

Ich fand das folgende Artikel , das für mich großartig funktionierte und beschreibt die Verwendung des Folgenden:

var load_this_javascript = function() { 
  // do some things 
}
$(document).ready(load_this_javascript)
$(window).bind('page:change', load_this_javascript)
2
Adrian Mann

Anstatt eine Variable zum Speichern der Funktion "ready" und zum Binden an die Ereignisse zu verwenden, möchten Sie möglicherweise das Ereignis ready auslösen, wenn page:load ausgelöst wird.

$(document).on('page:load', function() {
  $(document).trigger('ready');
});
2
wachunei

Ich dachte, ich lasse das hier für diejenigen, die auf Turbolinks 5 upgraden: Der einfachste Weg, Ihren Code zu reparieren, ist, von:

var ready;
ready = function() {
  // Your JS here
}
$(document).ready(ready);
$(document).on('page:load', ready)

zu:

var ready;
ready = function() {
  // Your JS here
}
$(document).on('turbolinks:load', ready);

Referenz: https://github.com/turbolinks/turbolinks/issues/9#issuecomment-184717346

2
tirdadc

Ich habe Folgendes getan, um sicherzustellen, dass die Dinge nicht zweimal ausgeführt werden:

$(document).on("page:change", function() {
     // ... init things, just do not bind events ...
     $(document).off("page:change");
});

Die Verwendung des Edelsteins jquery-turbolinks oder das Kombinieren von $(document).ready und $(document).on("page:load") oder die Verwendung von $(document).on("page:change") für sich verhält sich unerwartet - insbesondere, wenn Sie sich in der Entwicklung befinden.

2
Gray Kemmey

Normalerweise mache ich für meine Rails 4-Projekte Folgendes:

In application.js

function onInit(callback){
    $(document).ready(callback);
    $(document).on('page:load', callback);
}

Dann benutze ich in den restlichen .js-Dateien statt $(function (){})onInit(function(){})

1
muZk
$(document).ready(ready)  

$(document).on('turbolinks:load', ready)
1

Getestet haben so viele Lösungen endlich dazu gekommen. So oft wird Ihr Code definitiv nicht zweimal aufgerufen.

      var has_loaded=false;
      var ready = function() {
        if(!has_loaded){
          has_loaded=true;
           
          // YOURJS here
        }
      }

      $(document).ready(ready);
      $(document).bind('page:change', ready);
0
Simon Meyborg

Installieren Sie zuerst jquery-turbolinks gem. Vergessen Sie dann nicht, Ihre eingebundenen Javascript-Dateien vom Ende des Körpers Ihres application.html.erb in dessen <head> zu verschieben.

Wie hier beschrieben , wenn Sie den JavaScript-Link der Anwendung aus Gründen der Geschwindigkeitsoptimierung in die Fußzeile eingefügt haben, müssen Sie ihn in das Tag verschieben, damit er vor dem Inhalt im Tag geladen wird. Diese Lösung hat bei mir funktioniert.

0
Aboozar Rajabi