Rails 5: jak używać $ (document) .ready () z łączami turbo


84

Turbolinks zapobiega $(document).ready()uruchamianiu normalnych zdarzeń podczas wszystkich wizyt na stronie poza początkowym ładowaniem, co omówiono tutaj i tutaj . Jednak żadne z rozwiązań w połączonych odpowiedziach nie działa z Railsami 5. Jak mogę uruchomić kod na każdej wizycie na stronie, tak jak w poprzednich wersjach?

Odpowiedzi:


170

Zamiast słuchać readyzdarzenia, musisz podłączyć się do zdarzenia uruchamianego przez Turbolinks przy każdej wizycie na stronie.

Niestety Turbolinks 5 (który jest wersją, która pojawia się w Rails 5) został przepisany i nie używa tych samych nazw zdarzeń, co w poprzednich wersjach Turbolinks, przez co wymienione odpowiedzi zawodzą. To, co teraz działa, to odsłuchiwanie turbolinks: load event w następujący sposób:

$( document ).on('turbolinks:load', function() {
  console.log("It works on each visit!")
})

5
Tak. Tutaj również wyjaśniono. guide.rubyonrails.org/… . Sprawdź 5.2 Zdarzenia zmiany strony.
Indika K,

3
turbolinks: ładuj pożary dla mnie lokalnie, ale nie na Heroku. Widzę swój niestandardowy kod JavaScript w moich skompilowanych zasobach js, ale zdarzenie nie jest uruchamiane.
psparrow

to nie działa dobrze. Mam select2 i po zmianie strony iz powrotem mam dwa select2 (zduplikowane)
inye

3
Pomimo tego, co mówi dokument Rail, używam on('ready turbolinks:load')inaczej, mam pewne problemy na niektórych stronach
Cyril Duchon-Doris

1
Cześć Cyril, mam ten sam problem, tj. Muszę wyzwalać przy początkowym ładowaniu strony, a także turbolinks: ładowanie. Zadałem pytanie na ten temat na SO, stackoverflow.com/questions/41421496/… . Czy masz więcej informacji, dlaczego tak się dzieje? Czy używasz jquery-turbolinks (ja). Jedyną dobrą rzeczą jest to, że upewnia się, że twój kod jest idempotentny.
Obromios

59

Natywny JS:

document.addEventListener("turbolinks:load", function() {
    console.log('It works on each visit!');
});

11

W szynach 5 najłatwiejszym rozwiązaniem jest zastosowanie:

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

Zamiast $(document).ready. Działa jak marzenie.


10
Nie dodawaj readydo listy, w przeciwnym razie funkcja zostanie wykonana dwukrotnie. Jak powiedział github.com/turbolinks/turbolinks/#observing-navigation-events , powinieneś zrobić to w następujący sposób: javascript $(document).ready(function() { $(document).on('turbolinks:load', function() {} ) })
Xiaohui Zhang

@XiaohuiZhang Czy na pewno to zadziała ???? Bo jeśli $(document).readyzostanie wyzwolony, to przynajmniej w moich własnych scenariuszach nie potrzebowałbymturbolinks:load
Milad.Nozari

@XiaohuiZhang Jeśli twój skrypt ma działać na stronie z turbolinkami i na stronie bez, to nie będzie działać na stronie bez, ponieważ będzie potrzebować zdarzenia turbolinks: load, aby wykonać kod
escanxr

@escanxr Działa w obu przypadkach, możesz go wypróbować. ponieważ Turbolinks zawsze wywołuje zdarzenie „turbolinks: load” zawsze, gdy strona Turbolinks lub nie.
Xiaohui Zhang

2
@XiaohuiZhang Próbowałem z Turbolinks 5, nie działało. Jeśli turbolinks jest wyłączony na stronie, readywyzwalane jest tylko zdarzenie. Jeśli są turboliny, kod jest wywoływany dwukrotnie
escanxr

9

To jest moje rozwiązanie, nadpisanie jQuery.fn.ready, a następnie $(document).readydziała bez żadnych zmian:

jQuery.fn.ready = (fn)->
  $(this).on 'turbolinks:load', fn

Właśnie tego potrzebowałem. Działa to w przypadku bibliotek zewnętrznych, które również korzystają z documentwywołań zwrotnych. Dlaczego głos przeciw? Powinno to być bezpieczne, o ile turbolinki są używane w całej aplikacji, prawda?
Dylan Vander Berg

3

(Dla skryptu kawowego)

Używam: $(document).on 'turbolinks:load', ->

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


Zrobiłem to i nadal otrzymuję ten problem, jak powiedział @inye : github.com/mkhairi/materialize-sass/issues/130 . Używanie JS lub Coffee nie robi żadnej różnicy, przynajmniej NIE dla mnie.
alexventuraio

2
Cześć ludzie, co jest ogólnie nie tak z tą odpowiedzią?
atw

Domyślam się, że to jest coffeescript, a nie natywny javascript? Dałem mu +1, ponieważ to jest dokładnie to, co robię i działa na mnie (w moim pliku skryptu coffeescript)
aarona

tak !, to do skryptu kawowego :). Moim błędem było nie sprecyzowanie tego
fcabanasm

2

Oto rozwiązanie, które działa dla mnie, stąd :

  1. zainstalować gem 'jquery-turbolinks'

  2. dodaj ten plik .coffee do swojej aplikacji: https://github.com/turbolinks/turbolinks/blob/master/src/turbolinks/compatibility.coffee

  3. nazwij to turbolinks-compatibility.coffee

  4. w application.js

    //= require jquery
    //= require jquery_ujs
    //= require jquery.turbolinks
    //= require turbolinks
    //= require turbolinks-compatibility
    

A co z productionenv? Czy to przetestowałeś? Niektórzy mówią, że działa dobrze w developmenttrybie.
alexventuraio

6
Klejnot jest przestarzały
Mauro

1

Podczas gdy czekamy na naprawę tego naprawdę fajnego klejnotu, mogłem przejść do przodu, modyfikując następujące elementy;

  addCallback: (callback) ->
if $.turbo.isReady
  callback($)
$document.on 'turbo:ready', -> callback($)

do:

  addCallback: (callback) ->
if $.turbo.isReady
  callback($)
$document.on 'turbolinks:load', -> callback($)

Nie wiem jeszcze, czego to nie rozwiązuje, ale przy wstępnej inspekcji wydawało się, że działa dobrze.


-1

Użyj lekkich klejnotów jquery-turbolinks .

Umożliwia $(document).ready()pracę z Turbolinks bez zmiany istniejącego kodu.

Alternatywnie możesz zmienić $(document).ready()na jedną z:

$(document).on('page:fetch', function() { /* your code here */ });

$(document).on('page:change', function() { /* your code here */ });

w zależności od tego, który jest bardziej odpowiedni w Twojej sytuacji.


jquery-turbolinks nie obsługuje jeszcze Turbolinks 5 github.com/kossnocorp/jquery.turbolinks/issues/56
AndrewH

Masz rację, @ ​​AndrewH! Miejmy nadzieję, że wsparcie zostanie wkrótce dodane.
Vadim

2
Klejnot jquery-turbolinks został wycofany.
Nathan V
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.