Me encontré con un problema en mi aplicación Rails 4 al intentar organizar los archivos JS "a la manera de los rieles". Anteriormente estaban dispersos en diferentes puntos de vista. Los organicé en archivos separados y los compilé con la canalización de activos. Sin embargo, acabo de enterarme de que el evento "listo" de jQuery no se activa en los clics posteriores cuando se activa el enlace turbo. La primera vez que carga una página, funciona. Pero cuando hace clic en un enlace, todo lo que está dentro ready( function($) {
no se ejecutará (porque la página no se vuelve a cargar). Buena explicación: aquí .
Entonces, mi pregunta es: ¿Cuál es la forma correcta de garantizar que los eventos jQuery funcionen correctamente mientras están activados los enlaces turbo? ¿Envuelve los scripts en un oyente específico de Rails? ¿O tal vez los rieles tienen algo de magia que lo hace innecesario? Los documentos son un poco vagos sobre cómo debería funcionar esto, especialmente con respecto a la carga de múltiples archivos a través de los manifiestos como application.js.
fuente
var ready = function() { ... } $(document).ready(ready) $(document).on('page:load', ready)
¿Hay alguna preocupación por ambos.ready
y por'page:load'
ser activado?ready
se activa el evento. Si se trata de una carga de turbolinks, solopage:load
se dispara el evento. Es imposible para ambosready
ypage:load
ser despedidos en la misma página.page:load
eready
incluir una cadena separada por espacios para el primer argumento.$(document).on('page:load ready', ready);
El segundo argumento es simplemente una función, que se nombraready
, siguiendo el ejemplo de esta respuesta.Acabo de enterarme de otra opción para resolver este problema. Si carga la
jquery-turbolinks
gema , vinculará los eventos de Rails Turbolinks a losdocument.ready
eventos para que pueda escribir su jQuery de la manera habitual. Simplemente agregajquery.turbolinks
justo despuésjquery
en el archivo de manifiesto js (por defecto:)application.js
.fuente
//= require jquery.turbolinks
al manifiesto (por ejemplo, application.js).Recientemente encontré la forma más limpia y fácil de entender:
O
EDITAR
Si ha delegado eventos vinculados al
document
, asegúrese de adjuntarlos fuera de laready
función, de lo contrario, se recuperarán en cadapage:load
evento (haciendo que las mismas funciones se ejecuten varias veces). Por ejemplo, si tiene alguna llamada como esta:Sácalos de la
ready
función, así:Los eventos delegados vinculados al
document
no necesitan vincularse en elready
evento.fuente
ready()
función separada . Votos a favor adicionales para la explicación de eventos delegados vinculantes fuera de laready
función.$(document).on( "ready", handler ), deprecated as of jQuery 1.8.
jQuery / listasready
porción se invalida al usar la gema?Encontré esto en la documentación de Rails 4 , similar a la solución de DemoZluk pero un poco más corta:
O
Si tiene scripts externos que llaman
$(document).ready()
o si no puede molestarse en reescribir todo su JavaScript existente, entonces esta gema le permite seguir usando$(document).ready()
TurboLinks: https://github.com/kossnocorp/jquery.turbolinksfuente
Según las nuevas guías de rieles , la forma correcta es hacer lo siguiente:
o, en coffeescript:
No escuches el evento
$(document).ready
y solo se disparará un evento. Sin sorpresas, no es necesario usar la gema jquery.turbolinks .Esto funciona con los rieles 4.2 y superiores, no solo con los rieles 5.
fuente
"turbolinks:load"
evento funciona en Rails 4.2? Elturbolinks:
prefijo del evento se introdujo en los Nuevos Turbolinks y no se usa en Rails 4.2 IIRC que usa Turbolinks Classic . Considera probar"page:change"
si"turbolinks:load"
no funciona en tu aplicación anterior a Rails 5. Ver guías.rubyonrails.orgpage:change
o actualice los enlaces turbo. También encontré esto, puede ser relevante para algunos, donde turbolinks traduce eventos a los nombres de eventos antiguos: github.com/turbolinks/turbolinks/blob/v5.0.0/src/turbolinks/…alert "page has loaded!"
necesario sangrar para que la función de devolución de llamada la ejecute realmente?NOTA: Consulte la respuesta de @ SDP para obtener una solución limpia e integrada
Lo arreglé de la siguiente manera:
asegúrese de incluir application.js antes de que se incluyan los otros archivos js dependientes de la aplicación cambiando el orden de inclusión de la siguiente manera:
Defina una función global que maneje el enlace en
application.js
Ahora puedes unir cosas como:
fuente
ready
evento, esto significa que puede utilizar la forma "estándar" de inicialización:$(document).ready(function() { /* do your init here */});
. Se debe llamar a su código de inicio cuando se carga la página completa (-> sin turbolinks) y su código de inicio se debe ejecutar nuevamente cuando carga una página a través de turbolinks. Si desea ejecutar algún código sólo cuando se ha utilizado un Turbolink:$(document).on('page:load', function() { /* init only for turbolinks */});
Nada de lo anterior funciona para mí, resolví esto al no usar jQuery's $ (document) .ready, sino que utilicé addEventListener en su lugar.
fuente
fuente
turbolinks:load
en la primera carga de la página, Safari no y la forma en hacky para arreglarlo (activaciónturbolinks:load
deapplication.js
) obviamente rompe Chrome (que dispara dos veces con esto). Esta es la respuesta correcta. Definitivamente ir con los 2 eventosready
yturbolinks:load
.Tienes que usar:
de turbolinks doc .
fuente
O usa el
o utilice la función .on de jQuery para lograr el mismo efecto
ver aquí para más detalles: http://srbiv.github.io/2013/04/06/rails-4-my-first-run-in-with-turbolinks.html
fuente
En lugar de utilizar una variable para guardar la función "lista" y vincularla a los eventos, es posible que desee activar el
ready
evento siempre que se activepage:load
.fuente
Esto es lo que he hecho para garantizar que las cosas no se ejecuten dos veces:
Creo que usar la
jquery-turbolinks
gema o combinar$(document).ready
y /$(document).on("page:load")
o usar$(document).on("page:change")
solo se comporta inesperadamente, especialmente si estás en desarrollo.fuente
$(document).off
bit en esa función anónima de "cambio de página", obviamente alertará cuando llegue a esa página. Pero al menos en el desarrollo que ejecuta WEBrick, también alertará cuando haga clic en un enlace a otra página. En el peor de los casos, alerta dos veces cuando hago clic en un enlace a la página original.Encontré el siguiente artículo que funcionó muy bien para mí y detalla el uso de lo siguiente:
fuente
Pensé que dejaría esto aquí para aquellos que actualicen a Turbolinks 5 : la forma más fácil de arreglar su código es ir desde:
a:
Referencia: https://github.com/turbolinks/turbolinks/issues/9#issuecomment-184717346
fuente
fuente
turbolinks:load
evento se dispara para la carga de la página inicial, así como después de seguir los enlaces. Si adjunta un evento tanto already
evento estándar como alturbolinks:load
evento, se disparará dos veces la primera vez que visite una página.ready
que se dispare dos veces en las siguientes cargas de página. Por favor cámbielo o elimínelo.Probado tanta solución finalmente llegó a esto. Este código definitivamente no se llama dos veces.
fuente
Normalmente hago lo siguiente para mis proyectos de rails 4:
En
application.js
Luego, en el resto de los archivos .js, en lugar de usar
$(function (){})
, llamoonInit(function(){})
fuente
Primero, instale la
jquery-turbolinks
gema. Y luego, no se olvide de mover los archivos Javascript comprendidos desde el extremo del cuerpo de suapplication.html.erb
a su<head>
.Como se describe aquí , si ha puesto el enlace javascript de la aplicación en el pie de página por razones de optimización de velocidad, deberá moverlo a la etiqueta para que se cargue antes que el contenido de la etiqueta. Esta solución funcionó para mí.
fuente
Me encontré con mis funciones se duplicaron cuando se utiliza una función para
ready
yturbolinks:load
por lo que utiliza,De esa manera, sus funciones no se duplican si se admiten turbolinks
fuente