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. Еще одна потенциально важная деталь заключается в том, что содержимое файла projects.js обернуто в $(document).ready(function(){, Кроме того, я тестирую в режиме разработки, поэтому javascripts и css не объединяются конвейером ресурсов.

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

Обновить!

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

3 ответа

$(document).ready(function(){ на самом деле не работает с Turbolinks. Турболинки:

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

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

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

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

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

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

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

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

Решение этого уже доступно в этом Railscast

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

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

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

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

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

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

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

gem 'jquery-turbolinks'

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

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

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

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

});

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

Другие вопросы по тегам