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?

AndrewH
źródło

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!")
})
AndrewH
źródło
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!');
});
user464622
źródło
11

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

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

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

Milad.Nozari
źródło
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
Xiaohui Zhang
źródło
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() {...})

fcabanasm
źródło
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
    
ChaosPredictor
źródło
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.

Jason Ihaia
źródło
-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.

Vadim
źródło
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