Wystąpił problem w mojej aplikacji Rails 4, próbując uporządkować pliki JS „po torach”. Wcześniej były one rozrzucone po różnych widokach. Zorganizowałem je w osobne pliki i skompilowałem je z potokiem zasobów. Jednak właśnie dowiedziałem się, że „gotowe” zdarzenie jQuery nie uruchamia się przy kolejnych kliknięciach, gdy włączone jest łączenie turbo. Przy pierwszym załadowaniu strony działa. Ale kiedy klikniesz link, nic wewnątrz ready( function($) {
nie zostanie wykonane (ponieważ strona nie ładuje się 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 włączone są łącza Turbo? Czy pakujesz skrypty w odbiornik specyficzny dla Railsów? A może szyny mają jakąś magię, która czyni ją niepotrzebną? Dokumenty są nieco niejasne, jak to powinno działać, szczególnie w odniesieniu do ładowania wielu plików za pośrednictwem manifestów, takich jak application.js.
źródło
var ready = function() { ... } $(document).ready(ready) $(document).on('page:load', ready)
Czy jest jakiś problem dla obu.ready
i'page:load'
wyzwalane uzyskiwanie?ready
zdarzenie jest zwolniony. Jeśli jest to obciążenie turbolinks, tylkopage:load
zdarzenie jest zwolniony. Oba są niemożliweready
ipage:load
można je zwolnić na tej samej stronie.page:load
iready
dołączając ciąg rozdzielany spacją dla pierwszego argumentu.$(document).on('page:load ready', ready);
Drugi argument to po prostu funkcja, która przypadkowo nazywa sięready
zgodnie z przykładem tej odpowiedzi.Właśnie dowiedziałem się o innej opcji rozwiązania tego problemu. Jeśli włożysz ten
jquery-turbolinks
gem będzie wiązać wydarzenia Szyny Turbolinks dodocument.ready
zdarzeń, dzięki czemu można napisać jQuery w zwykły sposób. Po prostu dodajeszjquery.turbolinks
bezpośredniojquery
w pliku manifestu js (domyślnie:)application.js
.źródło
//= require jquery.turbolinks
do manifestu (np. Application.js).Ostatnio znalazłem najbardziej czysty i łatwy do zrozumienia sposób radzenia sobie z tym:
LUB
EDYCJA
Jeśli delegowałeś zdarzenia powiązane z
document
, upewnij się, że dołączasz je pozaready
funkcją, w przeciwnym razie odbijają się one przy każdympage:load
zdarzeniu (powodując wielokrotne uruchamianie tych samych funkcji). Na przykład, jeśli masz takie połączenia:Wyjmij je z
ready
funkcji, tak jak to:Zdarzenia delegowane powiązane z tym wydarzeniem
document
nie muszą być powiązaneready
.źródło
ready()
funkcji. Premia do głosowania za wyjaśnienie wiążących zdarzeń delegowanych pozaready
funkcją.$(document).on( "ready", handler ), deprecated as of jQuery 1.8.
jquery / readyready
część została unieważniona przy użyciu klejnotu?Znalazłem to w dokumentacji Rails 4 , podobnej do rozwiązania DemoZluka, ale nieco krótszej:
LUB
Jeśli masz zewnętrzne skrypty, które wywołują
$(document).ready()
lub nie możesz niepokoić się przepisywaniem wszystkich istniejących skryptów JavaScript, ten klejnot pozwala ci nadal używać$(document).ready()
TurboLink: https://github.com/kossnocorp/jquery.turbolinksźródło
Zgodnie z nowymi przewodnikami po szynach poprawnym sposobem jest wykonanie następujących czynności:
lub, w coffeescript:
Nie słuchaj wydarzenia
$(document).ready
i zostanie uruchomione tylko jedno wydarzenie. Bez niespodzianek, bez potrzeby używania klejnotu jquery.turbolinks .Działa to z szynami 4.2 i nowszymi, nie tylko z szynami 5.
źródło
"turbolinks:load"
wydarzenie działa w Rails 4.2?turbolinks:
Prefiks zdarzenia wprowadzono w Nowym Turbolinks i nie stosuje się szyn 4,2 IIRC który wykorzystuje Turbolinks Klasyczne . Zastanów się,"page:change"
czy"turbolinks:load"
nie działa w aplikacji wcześniejszej niż Rails 5. Patrz guide.rubyonrails.org/v4.2.7/…page:change
lub zaktualizuj turbolinki. Stwierdzono również, że może to dotyczyć niektórych, w których turbolinks tłumaczy zdarzenia na stare nazwy zdarzeń: github.com/turbolinks/turbolinks/blob/v5.0.0/src/turbolinks/…alert "page has loaded!"
konieczne jest wcięcie, aby faktycznie było uruchamiane przez funkcję wywołania zwrotnego?UWAGA: Zobacz @ SDP, aby uzyskać czyste, wbudowane rozwiązanie
Naprawiłem to w następujący sposób:
upewnij się, że dołączasz plik application.js, zanim inne pliki js zależne od aplikacji zostaną dołączone, zmieniając kolejność dołączania w następujący sposób:
Zdefiniuj funkcję globalną, która obsługuje wiązanie
application.js
Teraz możesz wiązać takie rzeczy jak:
źródło
ready
wypadku, oznacza to, można użyć „standard” sposób inicjalizacji:$(document).ready(function() { /* do your init here */});
. Twój kod inicjujący powinien być wywoływany, gdy ładowana jest cała strona (-> bez turbolinków), a kod inicjujący powinien być wykonywany ponownie, gdy ładujesz stronę za pomocą turbolinków. Jeśli chcesz wykonać kod TYLKO, gdy użyto turbolinka:$(document).on('page:load', function() { /* init only for turbolinks */});
Żadne z powyższych nie działa dla mnie, rozwiązałem to nie używając jQuery's $ (document) .ready, ale zamiast tego użyłem addEventListener.
źródło
źródło
turbolinks:load
się przy pierwszym ładowaniu strony, Safari nie działa, a hacky sposób, aby to naprawić (turbolinks:load
włączenieapplication.js
) oczywiście psuje Chrome (który uruchamia się dwa razy z tym). To jest poprawna odpowiedź. Zdecydowanie skorzystaj z 2 wydarzeńready
iturbolinks:load
.Musisz użyć:
z turbolinks doc .
źródło
Albo użyj
lub użyj funkcji .on jQuery, aby uzyskać ten sam efekt
zobacz tutaj po więcej szczegółów: http://srbiv.github.io/2013/04/06/rails-4-my-first-run-in-with-turbolinks.html
źródło
Zamiast używać zmiennej do zapisywania funkcji „gotowości” i wiązania jej ze zdarzeniami, możesz chcieć wywołać
ready
zdarzenie za każdym razem, gdy zostaniepage:load
wyzwolone.źródło
Oto, co zrobiłem, aby upewnić się, że rzeczy nie są wykonywane dwukrotnie:
Uważam, że używanie
jquery-turbolinks
klejnotu lub łączenie$(document).ready
i /$(document).on("page:load")
lub używanie$(document).on("page:change")
zachowuje się nieoczekiwanie - szczególnie jeśli jesteś w fazie rozwoju.źródło
$(document).off
fragmentu tej anonimowej funkcji „page: change” powyżej, to oczywiście zaalarmuję, kiedy dojdę do tej strony. Ale przynajmniej w fazie projektowania WEBrick będzie także ostrzegał, gdy kliknę link do innej strony. Gorzej, alarmuje dwa razy, kiedy kliknę link z powrotem do oryginalnej strony.Znalazłem następujący artykuł, który był dla mnie świetny i szczegółowo opisałem następujące zastosowania:
źródło
Pomyślałem, że zostawię to tutaj dla tych, którzy dokonują aktualizacji do Turbolinks 5 : najprostszym sposobem na poprawienie kodu jest przejście z:
do:
Odniesienie: https://github.com/turbolinks/turbolinks/issues/9#issuecomment-184717346
źródło
źródło
turbolinks:load
Zdarzenie dla wstępnego ładowania strony, jak również po wykonaniu połączeń. Jeśli dołączysz wydarzenie zarówno doready
zdarzenia standardowego , jak iturbolinks:load
wydarzenia, będzie ono uruchamiane dwukrotnie przy pierwszej wizycie na stronie.ready
dwukrotne uruchomienie przy kolejnych ładowaniach stron. Zmień lub usuń.Testowane tak wiele rozwiązań w końcu do tego doszło. Tyle twoich kodów zdecydowanie nie jest wywoływanych dwukrotnie.
źródło
Zazwyczaj wykonuję następujące czynności dla moich projektów z szynami 4:
W
application.js
Następnie w pozostałych plikach .js zamiast za pomocą
$(function (){})
I callonInit(function(){})
źródło
Najpierw zainstaluj
jquery-turbolinks
klejnot. A potem nie zapomnij przenieść dołączonych plików JavaScript z końca swojego ciałaapplication.html.erb
do jego<head>
.Jak opisano tutaj , jeśli umieścisz link javascript aplikacji w stopce ze względu na optymalizację prędkości, musisz przenieść go do tagu, aby załadował się przed zawartością w tagu. To rozwiązanie działało dla mnie.
źródło
Znalazłem moje funkcje podwoiła się podczas korzystania z funkcji dla
ready
iturbolinks:load
tak kiedyś,W ten sposób twoje funkcje nie podwajają się, jeśli obsługiwane są turbolinki!
źródło