Rails 4: Jak używać $(document).ready () with turbo-links

Napotkałem problem w mojej aplikacji Rails 4 podczas próby zorganizowania plików JS "the rails way". Wcześniej były one rozrzucone po różnych widokach. Zorganizowałem je w osobne pliki i skompilowałem za pomocą potoku zasobów. Jednak właśnie dowiedziałem się, że zdarzenie "ready" jQuery nie odpala się przy kolejnych kliknięciach, gdy turbo-linkowanie jest włączone. Przy pierwszym załadowaniu strony działa. Ale po kliknięciu linku wszystko wewnątrz ready( function($) { nie zostanie wykonane (ponieważ strona nie faktycznie załadować ponownie). Dobre wyjaśnienie: Tutaj .

Więc moje pytanie brzmi: jaki jest właściwy sposób, aby upewnić się, że zdarzenia jQuery działają poprawnie, gdy turbo-linki są włączone? Czy pakujesz skrypty w specyficzny dla Rails słuchacz? A może rails ma jakąś magię, która sprawia, że jest niepotrzebna? Dokumenty są nieco niejasne, jak to powinno działać, zwłaszcza w odniesieniu do ładowania wielu plików za pośrednictwem aplikacji podobnej do manifestu.js.

Author: Community, 2013-09-12

19 answers

Oto co robię... CoffeeScript:

ready = ->

  ...your coffeescript goes here...

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

Ostatni wiersz nasłuchuje wczytywania strony, co spowoduje uruchomienie linków turbo.

Edit ...dodanie wersji Javascript (na żądanie):

var ready;
ready = function() {

  ...your javascript goes here...

};

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

Edycja 2 ...Dla Rails 5 (Turbolinks 5) page:load staje się turbolinks:load i będzie nawet odpalany przy początkowym obciążeniu. Możemy więc po prostu wykonać następujące czynności:

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

  ...your javascript goes here...

});
 538
Author: Meltemi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-29 00:50:51

Właśnie dowiedziałem się o innej opcji rozwiązania tego problemu. Jeśli wczytasz gem jquery-turbolinks spowoduje to powiązanie zdarzeń Rails Turbolinks ze zdarzeniami document.ready, dzięki czemu będziesz mógł pisać swoje jQuery w zwykły sposób. Wystarczy dodać jquery.turbolinks zaraz po jquery w pliku manifestu js (domyślnie: application.js).

 233
Author: emersonthis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-24 00:25:38

Ostatnio znalazłem najbardziej czysty i łatwy do zrozumienia sposób radzenia sobie z tym:

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

Lub

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

EDIT
Jeśli masz delegowane zdarzenia powiązane z document, Upewnij się, że dołączasz je poza funkcją ready, w przeciwnym razie będą one odbijane przy każdym zdarzeniu page:load (powodując wielokrotne uruchamianie tych samych funkcji). Na przykład, jeśli masz jakieś wywołania takie jak:

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

Wyjmij je z funkcji ready, Jak to:

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

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

Zdarzenia delegowane związane z document nie muszą być związane z ready.

 196
Author: Dezl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-14 07:11:15

Znalazłem to w Rails 4 documentation , podobne do rozwiązania Demozluka, ale nieco krótsze:

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

Lub

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

Jeśli masz zewnętrzne skrypty, które wywołują $(document).ready() lub jeśli nie masz problemu z przepisaniem całego istniejącego JavaScript, ten klejnot pozwala Ci używać {[2] } z Turbolinkami: https://github.com/kossnocorp/jquery.turbolinks

 90
Author: migu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-15 01:23:29

Zgodnie z nowymi prowadnicami rails, poprawnym sposobem jest wykonanie następujących czynności:

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

Lub w coffeescript:

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

Nie nasłuchuj zdarzenia $(document).ready i zostanie wywołane tylko jedno zdarzenie. Bez niespodzianek, bez potrzeby używania jquery.turbolinks gem.

Działa to z rails 4.2 i nowszymi, nie tylko rails 5.

 73
Author: vedant,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-19 11:59:21

Uwaga: Zobacz odpowiedź @SDP dla czystego, wbudowanego rozwiązania

Naprawiłem to w następujący sposób:

Upewnij się, że dołączasz aplikację.js zanim inne zależne od aplikacji Pliki JS zostaną dołączone, zmieniając kolejność dołączania w następujący sposób:

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

Zdefiniuj funkcję globalną, która obsługuje Wiązanie w application.js

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

Teraz możesz wiązać rzeczy takie jak:

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

// equivalent in javascript:
onLoad(function() {
  $('a.clickable').click(function() {
    alert('link clicked');
});
 10
Author: sled,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-03 22:48:38

Żadne z powyższych nie działa dla mnie, rozwiązałem to nie używając jQuery ' s $(document).gotowy, ale zamiast tego użyj addEventListener.

document.addEventListener("turbolinks:load", function() {
  // do something
});
 8
Author: RockL,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-13 12:05:45

Albo użyć

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

Lub użyj jQuery .on funkcja osiągnąć ten sam efekt

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

Zobacz tutaj, aby uzyskać więcej szczegółów: http://srbiv.github.io/2013/04/06/rails-4-my-first-run-in-with-turbolinks.html

 3
Author: derekyau,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-12 17:50:47

Zamiast używać zmiennej do zapisywania funkcji "ready" i wiązania jej ze zdarzeniami, możesz chcieć wywołać zdarzenie ready za każdym razem, gdy page:load wyzwoli.

$(document).on('page:load', function() {
  $(document).trigger('ready');
});
 2
Author: wachunei,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-25 18:45:25

Oto, co zrobiłem, aby upewnić się, że rzeczy nie są wykonywane dwa razy:

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

Uważam, że używanie gem jquery-turbolinks lub łączenie $(document).ready i $(document).on("page:load") lub używanie $(document).on("page:change") samo w sobie zachowuje się nieoczekiwanie-szczególnie jeśli jesteś w fazie rozwoju.

 2
Author: Gray Kemmey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-19 08:09:54

Znalazłem następujący Artykuł , który zadziałał dla mnie świetnie i szczegółowo opisuje zastosowanie:

var load_this_javascript = function() { 
  // do some things 
}
$(document).ready(load_this_javascript)
$(window).bind('page:change', load_this_javascript)
 2
Author: Adrian Mann,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-21 14:54:02

Pomyślałem, że zostawię to tutaj dla tych, którzy przechodzą do Turbolinks 5 : najprostszym sposobem na poprawienie kodu jest przejście z:

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

Do:

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

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

 2
Author: tirdadc,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-01 03:13:13

Musisz użyć:

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

Z turbolinks doc .

 2
Author: Gian Franco Fioriello,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-18 00:13:21
$(document).on 'ready turbolinks:load', ->
  console.log '(document).turbolinks:load'
 2
Author: Sukeerthi Adiga,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-28 10:20:11
$(document).ready(ready)  

$(document).on('turbolinks:load', ready)
 1
Author: Konstantinos Mou,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-14 06:47:48
 <%= link_to 'Edit', edit_article_path(article), 'data-no-turbolink' => true %>

Może możesz użyć tak, aby użyć "ready", to tak jak Zamknij turbolink.

 0
Author: Alan Wang,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-04 08:05:34

Najpierw zainstaluj jquery-turbolinks gem. Następnie nie zapomnij przenieść dołączonych plików Javascript z końca ciała application.html.erb do jego <head>.

Jak opisano tutaj , jeśli umieściłeś link JavaScript aplikacji w stopce ze względu na optymalizację prędkości, musisz przenieść go do tagu, aby ładował się przed zawartością w tagu. To rozwiązanie zadziałało dla mnie.

 0
Author: Aboozar Rajabi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-21 09:58:11

Testowane tak wiele rozwiązań w końcu przyszedł do tego. Tyle Twój kod na pewno nie jest wywoływany dwa razy.

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

      $(document).ready(ready);
      $(document).bind('page:change', ready);
 0
Author: Simon Meyborg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-01 10:04:14

Zazwyczaj wykonuję następujące czynności dla moich projektów rails 4:

W application.js

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

Następnie w pozostałej części .Pliki js, zamiast używać $(function (){}) wywołuję onInit(function(){})

 0
Author: muZk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-16 18:49:46