Rails 4 turbo-link предотвращает работу сценариев jQuery

Я создаю приложение Rails 4, и у меня есть несколько разбросанных js файлов, которые я пытаюсь включить в "путь рельсов". Я переместил jquery-плагины в /vendor/assets/javascripts, и я обновил манифест (application.js), чтобы потребовать их. Когда я загружаю страницы локально, я вижу, что они отображаются правильно.

Однако я получаю непоследовательное поведение от одного из скомпилированных скриптов. У меня есть специфический для контроллера файл js, называемый projects.js, на который ссылается в application.js с помощью require_tree .:

//= require jquery
//= require jquery_ujs
//= require turbolinks
//= require bootstrap.min
//= require jquery.form.min
//= require_tree .

Я вижу, что файл включен правильно, и он работает... в половине случаев. Другая половина времени, материал в projects.js, кажется, ничего не делает (это в основном jquery-анимация и некоторые запросы ajax). Когда это не сработает, я нажимаю кнопки пару раз, ничего не произойдет, и тогда я выброшу эту ошибку:

Uncaught TypeError: Cannot read property 'position' of null 
turbolinks.js?body=1:75

Это никогда не случалось, когда скрипты находились в отдельных представлениях (неправильный путь), поэтому я уверен, что проблема не в моем javascript-коде. Еще одна потенциально важная информация заключается в том, что материал в проектах .js завернут в $(document).ready(function(){. Кроме того, я тестирую в режиме разработки, поэтому javascripts и css не объединены конвейером активов.

Любая идея, что здесь происходит? Я новичок в Rails, но я сделал все возможное, чтобы следовать всем соглашениям.

Обновление

Это предсказуемо, когда мои сценарии проекта не работают. Загрузка первой страницы работает каждый раз. Затем я нажимаю одну ссылку на новую страницу, которая использует мое поведение project.js, а вторая страница никогда не работает. Я нажимаю несколько раз и в конечном итоге бросаю ошибку выше. Я все еще не уверен, почему, но я подозреваю, что это связано с турбосвязкой.

Ответ 1

$(document).ready(function(){ не работает с Turbolinks. Turbolinks:

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

Таким образом, страница загружается только один раз, а затем детали заменяются по мере необходимости. Поскольку страница загружается только один раз, ваши обратные вызовы $(document).ready() запускаются только при первом посещении сайта, при переключении страниц вы не получите больше событий, связанных с подготовкой документов, поскольку Turbolinks фактически не переключает страницы. Из точное руководство:

С Turbolinks страницы будут меняться без полной перезагрузки, поэтому вы не можете полагаться на DOMContentLoaded или jQuery.ready() для запуска вашего кода. Вместо этого Turbolinks запускает события в документе, чтобы обеспечить привязку к жизненному циклу страницы.

Вероятно, вы хотите прослушать одно из событий Turbolinks:

  • page:change страница была проанализирована и изменена на новую версию и на DOMContentLoaded
  • [...]
  • page:load запускается в конце процесса загрузки.

page:change обычно является тем, что вы ищете, поскольку он запускается при загрузке новой страницы и восстановлении страницы из кеша страниц Turbolinks.

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

Другой вариант - использовать jquery.turbolinks, чтобы исправить все для вас. Я не использовал это, но другие люди используют его для хорошего эффекта.

Ответ 2

Решение этого уже доступно на этом railscast

Вот один пример (тот, который мне нравится использовать).

ready = ->
  # ..... your js

$(document).ready(ready)
$(document).on('page:load', ready)

Существует также жемчужина, которая решает эту проблему таким образом, чтобы вы продолжали делать это по-старому. Он работает очень хорошо:)

Ответ 3

Я понимаю, что этот ответ REAAAAAAALLLLLLLYYYYY Поздно... но я решил, что добавлю его.

У меня была эта проблема на прошлой неделе. При попытке заставить Foundation работать.

Сначала я добавил:

gem 'jquery-turbolinks'

Затем поместил его в application.js так:

//= require jquery.turbolinks
//= require jquery_ujs
//= require turbolinks
//= require_tree .

а затем я добавил это прямо под ним:

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

});

и все сработало для меня. Надеюсь, это поможет!