Rails 5: как использовать $ (document) .ready () с турбо-ссылками


85

Turbolinks предотвращает $(document).ready()запуск обычных событий при всех посещениях страницы, кроме начальной загрузки, как описано здесь и здесь . Однако ни одно из решений в связанных ответах не работает с Rails 5. Как я могу запускать код при каждом посещении страницы, как в предыдущих версиях?

Ответы:


170

Вместо того, чтобы слушать readyсобытие, вам нужно подключиться к событию, запускаемому Turbolinks при каждом посещении страницы.

К сожалению, Turbolinks 5 (версия, которая появляется в Rails 5) была переписана и не использует те же имена событий, что и в предыдущих версиях Turbolinks, что приводит к сбою упомянутых ответов. Что теперь работает, так это прослушивание события turbolinks: load следующим образом:

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

5
Да. Объясняется и здесь. guides.rubyonrails.org/… . Отметьте 5.2 События смены страницы.
Indika K

3
turbolinks: загрузка срабатывает у меня локально, но не на Heroku. Я вижу свой собственный код javascript в моих скомпилированных активах js, но событие не запускается.
psparrow

3
Несмотря на то, что написано в документации Rail, я использую, в on('ready turbolinks:load')противном случае у меня проблемы на некоторых страницах
Сирил Дюшон-Дорис

1
Привет, Сирил, у меня та же проблема, то есть мне нужно запускать при начальной загрузке страницы, а также turbolinks: load. Я задал вопрос об этом в SO, stackoverflow.com/questions/41421496/… . Есть ли у вас какое-нибудь представление о том, почему это так? Вы используете jquery-turbolinks (я). Единственное, что хорошо - это гарантирует, что ваш код идемпотентен.
Obromios

1
Это другое для рельсов 6?
Stevec

60

Собственный JS:

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

11

В рельсах 5 проще всего использовать:

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

Вместо $(document).ready. Работает как шарм.


10
Не добавляйте readyв список, иначе функция будет выполнена дважды. Как сказано на github.com/turbolinks/turbolinks/#observing-navigation-events , вы должны сделать это так: javascript $(document).ready(function() { $(document).on('turbolinks:load', function() {} ) })
Xiaohui Zhang

@XiaohuiZhang Ты уверен, что это сработает ???? Потому что если $(document).readyсработает, то, по крайней мере, в моих собственных сценариях, мне не понадобитсяturbolinks:load
Милад Нозари

@XiaohuiZhang Если ваш скрипт должен работать на странице с турболинками и на странице без них, он не будет работать на странице без него, потому что для выполнения кода ему потребуется событие turbolinks: load
escanxr

@escanxr Работает и то, и другое, можете попробовать. потому что Turbolinks всегда запускает событие "turbolinks: load" независимо от того, открывается страница Turbolinks или нет.
Xiaohui Zhang

2
@XiaohuiZhang Я пробовал с Turbolinks 5, не сработало. Если турболинки отключены на странице, readyзапускается только событие. Если есть турболинки, код вызывается дважды
escanxr

9

Это мое решение, переопределить jQuery.fn.ready, а затем $(document).readyработает без каких-либо изменений:

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

Это именно то, что мне нужно. Это работает для внешних библиотек, которые также полагаются на documentобратные вызовы. Почему голос против? Это должно быть безопасно, пока турболинки используются во всем приложении, верно?
Дилан Вандер Берг

3

(Для кофе)

Я использую: $(document).on 'turbolinks:load', ->

Вместо: $(document).on('turbolinks:load', function() {...})


Я сделал это, и у меня все еще возникает эта проблема, как сказал @inye: github.com/mkhairi/materialize-sass/issues/130 . Использование JS или Coffee на самом деле не имеет никакого значения, по крайней мере, для меня.
alexventuraio

2
Привет, ребята, а что вообще не так с этим ответом?
atw

Я предполагаю, что это coffeescript, а не собственный javascript? Я поставил ему +1, потому что это именно то, что я делаю, и это работает для меня (в моем файле coffeescript)
Аарона

да !, это для coffeescript :). Моя ошибка заключалась в том, что я не указал это
fcabanasm

2

Вот решение, которое работает для меня, отсюда :

  1. установить gem 'jquery-turbolinks'

  2. добавьте этот файл .coffee в свое приложение: https://github.com/turbolinks/turbolinks/blob/master/src/turbolinks/compatibility.coffee

  3. назовите его turbolinks-compatibility.coffee

  4. в application.js

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

А как насчет productionenv? Вы это проверили? Некоторые говорят, что в developmentрежиме он работает нормально .
alexventuraio

6
Драгоценный камень устарел
Мауро

1

Пока мы ждем исправления этого действительно крутого драгоценного камня, я смог продвинуться вперед, изменив следующее;

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

кому:

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

Я еще не знаю, что это не решает, но при первоначальной проверке казалось, что это работает хорошо.


0

Используйте легкий гем jquery-turbolinks .

Это позволяет $(document).ready()работать с Turbolinks без изменения существующего кода.

В качестве альтернативы вы можете выбрать $(document).ready()один из следующих вариантов:

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

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

в зависимости от того, какой из них более уместен в вашей ситуации.


jquery-turbolinks еще не поддерживает Turbolinks 5 github.com/kossnocorp/jquery.turbolinks/issues/56
AndrewH

Ты прав, @AndrewH! Надеюсь, поддержка скоро будет добавлена.
Вадим

2
Гем jquery-turbolinks устарел.
Nathan V

0

чистый современный js:

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

document.addEventListener("load", onLoad)
document.addEventListener("turbolinks:load", onLoad)
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.