Rails 5: como usar $ (document) .ready () con turbo-links


84

Turbolinks evita que los $(document).ready()eventos normales se activen en todas las visitas a la página, además de la carga inicial, como se explica aquí y aquí . Sin embargo, ninguna de las soluciones de las respuestas vinculadas funciona con Rails 5. ¿Cómo puedo ejecutar código en cada visita a la página como en versiones anteriores?

Respuestas:


170

En lugar de escuchar el readyevento, debe conectarse a un evento activado por Turbolinks para cada visita a la página.

Desafortunadamente, Turbolinks 5 (que es la versión que aparece en Rails 5) se ha reescrito y no usa los mismos nombres de eventos que en versiones anteriores de Turbolinks, lo que provoca que las respuestas mencionadas fallen. Lo que funciona ahora es escuchar los turbolinks: load event así:

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

5
Si. Explicado aquí también. guides.rubyonrails.org/… . Compruebe 5.2 Eventos de cambio de página.
Indika K

3
turbolinks: cargue incendios para mí localmente, pero no en Heroku. Veo mi código javascript personalizado en mis activos js compilados, pero el evento no se activa.
psparrow

esto no funciona bien. Tengo un select2 y al cambiar la página y volver tengo dos select2 (duplicados)
inye

3
A pesar de lo que dice el documento de Rail, estoy usando, de lo on('ready turbolinks:load')contrario, tengo algunos problemas en algunas páginas
Cyril Duchon-Doris

1
Hola Cyril, tengo el mismo problema, es decir, necesito activar la carga de la página inicial y los enlaces turbo: carga. He hecho una pregunta sobre esto en SO, stackoverflow.com/questions/41421496/… . ¿Tiene alguna idea más clara de por qué esto es así? ¿Estás usando jquery-turbolinks (lo estoy)? Lo único bueno es que se asegura de que su código sea idempotente.
Obromios

59

JS nativo:

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

11

En rails 5 la solución más sencilla es utilizar:

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

En lugar de $(document).ready. Funciona de maravilla.


10
No agregue readya la lista, de lo contrario, la función se ejecutará dos veces. Como dijo github.com/turbolinks/turbolinks/#observing-navigation-events , debe hacerlo así: javascript $(document).ready(function() { $(document).on('turbolinks:load', function() {} ) })
Xiaohui Zhang

@XiaohuiZhang ¿¿Estás seguro de que va a funcionar ???? Porque si $(document).readyse activa, al menos en mis propios escenarios, no lo necesitaríaturbolinks:load
Milad.Nozari

@XiaohuiZhang Si su script tiene que funcionar en una página con turbolinks y en una página sin, eso no funcionará en la página sin, porque necesitará el evento turbolinks: load para ejecutar el código
escanxr

@escanxr Funciona tanto, puedes probarlo. porque Turbolinks siempre activa el evento "turbolinks: load" cuando hay una página de Turbolinks o no.
Xiaohui Zhang

2
@XiaohuiZhang Probé con Turbolinks 5, no funcionó. Si turbolinks está desactivado en la página, solo readyse activa el evento. Si hay enlaces turbo, el código se llama dos veces
escanxr

9

Esta es mi solución, anular jQuery.fn.ready, luego $(document).readyfunciona sin ningún cambio:

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

Esto es exactamente lo que necesitaba. Esto también funciona para bibliotecas externas que dependen de documentdevoluciones de llamada. ¿Por qué el voto negativo? Esto debería ser seguro siempre que se utilicen turbolinks en toda la aplicación, ¿verdad?
Dylan Vander Berg

3

(Para coffeescript)

Yo suelo: $(document).on 'turbolinks:load', ->

En vez de: $(document).on('turbolinks:load', function() {...})


He hecho eso y sigo recibiendo este problema como dijo @inye : github.com/mkhairi/materialize-sass/issues/130 . Usar JS o Coffee realmente no hace ninguna diferencia, al menos NO para mí.
alexventuraio

2
Hola amigos, ¿qué hay de malo en esta respuesta en general?
atw

Supongo que esto es coffeescript y no javascript nativo. Le di un +1 porque esto es exactamente lo que estoy haciendo y funciona para mí (en mi archivo coffeescript)
aarona

¡sí !, es para coffeescript :). Mi error fue no especificarlo
fcabanasm

2

Aquí hay una solución que funciona para mí, desde aquí :

  1. Instalar en pc gem 'jquery-turbolinks'

  2. agregue este archivo .coffee a su aplicación: https://github.com/turbolinks/turbolinks/blob/master/src/turbolinks/compatibility.coffee

  3. asígnele el nombre turbolinks-compatibility.coffee

  4. en application.js

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

¿Y en productionenv? ¿Lo has probado? Algunas personas dicen que funciona bien en el developmentmodo.
alexventuraio

6
La gema está obsoleta
Mauro

1

Mientras esperamos la solución de esta joya realmente genial, pude seguir adelante modificando lo siguiente;

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

a:

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

Todavía no sé lo que esto no resuelve, pero pareció funcionar bien en la inspección inicial.


-1

Utilice los jquery-turbolinks de gemas ligeras .

Hace que $(document).ready()funcione con Turbolinks sin cambiar el código existente.

Alternativamente, puede cambiar $(document).ready()a uno de:

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

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

dependiendo de cuál sea más apropiado en su situación.


jquery-turbolinks aún no es compatible con Turbolinks 5 github.com/kossnocorp/jquery.turbolinks/issues/56
AndrewH

¡Tienes razón, @AndrewH! Con suerte, el soporte se agregará pronto.
Vadim

2
La gema jquery-turbolinks ha quedado obsoleta.
Nathan V
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.