Rails 5: come usare $ (document) .ready () con i turbo-link


85

Turbolinks impedisce l'attivazione di $(document).ready()eventi normali su tutte le visite alle pagine oltre al caricamento iniziale, come discusso qui e qui . Tuttavia, nessuna delle soluzioni nelle risposte collegate funziona con Rails 5. Come posso eseguire il codice su ogni visita di pagina come nelle versioni precedenti?

Risposte:


170

Piuttosto che ascoltare l' readyevento, devi collegarti a un evento lanciato da Turbolinks per ogni visita alla pagina.

Sfortunatamente, Turbolinks 5 (che è la versione che appare in Rails 5) è stato riscritto e non utilizza gli stessi nomi di eventi delle versioni precedenti di Turbolinks, causando il fallimento delle risposte menzionate. Ciò che funziona ora è ascoltare l' evento turbolinks: load in questo modo:

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

5
Sì. Spiegato anche qui. guide.rubyonrails.org/… . Selezionare 5.2 Eventi di cambio pagina.
Indika K

3
turbolink: carica i fuochi per me localmente, ma non su Heroku. Vedo il mio codice javascript personalizzato nelle risorse js compilate, ma l'evento non viene attivato.
psparrow

3
Nonostante quello che dice il documento Rail, sto usando on('ready turbolinks:load')altrimenti ho qualche problema su alcune pagine
Cyril Duchon-Doris

1
Ciao Cyril, sto riscontrando lo stesso problema, ovvero è necessario attivare il trigger al caricamento iniziale della pagina e turbolink: load. Ho posto una domanda su questo su SO, stackoverflow.com/questions/41421496/… . Hai altre informazioni sul motivo per cui è così? Stai usando jquery-turbolinks (io sono). L'unica cosa buona è che si assicura che il tuo codice sia idempotente.
Obromios

1
È diverso per i binari 6?
stevec

60

JS nativo:

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

11

In rails 5 la soluzione più semplice è usare:

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

Invece di $(document).ready. Funziona come un fascino.


10
Non aggiungere readyalla lista, altrimenti la funzione verrà eseguita due volte. Come ha detto github.com/turbolinks/turbolinks/#observing-navigation-events , dovresti farlo in questo modo: javascript $(document).ready(function() { $(document).on('turbolinks:load', function() {} ) })
Xiaohui Zhang

@XiaohuiZhang Sei sicuro che funzionerà ???? Perché se $(document).readyviene attivato, almeno nei miei scenari, non avrei bisogno diturbolinks:load
Milad.Nozari

@XiaohuiZhang Se il tuo script deve funzionare su una pagina con turbolink e su una pagina senza, questo non funzionerà sulla pagina senza, perché avrà bisogno dell'evento turbolinks: load per eseguire il codice
escanxr

@escanxr Funziona entrambi, puoi provarlo. perché Turbolinks attiva sempre l'evento "turbolinks: load" ogni volta che una pagina Turbolinks o meno.
Xiaohui Zhang

2
@XiaohuiZhang Ho provato con Turbolinks 5, non ha funzionato. Se turbolinks è disabilitato nella pagina, readyviene attivato solo l' evento. Se sono presenti turbolink, il codice viene chiamato due volte
escanxr

9

Questa è la mia soluzione, sovrascrivi jQuery.fn.ready, quindi $(document).readyfunziona senza alcuna modifica:

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

Questo è esattamente ciò di cui avevo bisogno. Funziona anche per le librerie esterne che si basano sui documentcallback. Perché il voto negativo? Questo dovrebbe essere sicuro fintanto che i turbolink vengono utilizzati durante l'intera applicazione, giusto?
Dylan Vander Berg

3

(Per coffeescript)

Io uso: $(document).on 'turbolinks:load', ->

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


L'ho fatto e ricevo ancora questo problema come ha detto @inye: github.com/mkhairi/materialize-sass/issues/130 . Usare JS o Coffee non fa davvero alcuna differenza, almeno NON per me.
alexventuraio

2
Ciao gente, cosa c'è di sbagliato in questa risposta in generale?
ATW

La mia ipotesi è che questo sia coffeescript e non javascript nativo? Ho dato un +1 perché questo è esattamente quello che sto facendo e funziona per me (nel mio file coffeescript)
aarona

sì !, è per coffeescript :). Il mio errore è stato non specificarlo
fcabanasm

2

Ecco la soluzione che funziona per me, da qui :

  1. installare gem 'jquery-turbolinks'

  2. aggiungi questo file .coffee alla tua app: https://github.com/turbolinks/turbolinks/blob/master/src/turbolinks/compatibility.coffee

  3. chiamalo turbolinks-compatibility.coffee

  4. su application.js

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

E in productionenv? L'hai provato? Ci sono alcune persone che dicono che funziona bene in developmentmodalità.
alexventuraio

6
La chicca è deprecata
Mauro

1

Mentre attendiamo la correzione di questa gemma davvero interessante, sono stato in grado di andare avanti modificando quanto segue;

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

per:

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

Non sono ancora a conoscenza di cosa questo non risolva, ma sembrava funzionare bene all'ispezione iniziale.


0

Usa la gemma leggera jquery-turbolinks .

Esso rende $(document).ready() con Turbolink senza modificare il codice esistente.

In alternativa, puoi passare $(document).ready()a uno di:

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

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

a seconda di quale è più appropriato nella tua situazione.


jquery-turbolinks non supporta ancora Turbolinks 5 github.com/kossnocorp/jquery.turbolinks/issues/56
AndrewH

Hai ragione, @AndrewH! Si spera che il supporto venga aggiunto presto.
Vadim

2
La gemma jquery-turbolinks è stata deprecata.
Nathan V

0

js moderno puro:

const onLoad = () => {
  alert("works")
}

document.addEventListener("load", onLoad)
document.addEventListener("turbolinks:load", onLoad)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.