Рельсы 4: Как использовать $(документ).ready() с turbo-links
я столкнулся с проблемой в моем приложении Rails 4 при попытке организовать JS-файлы "the rails way". Ранее они были разбросаны по разным точкам зрения. Я организовал их в отдельные файлы и скомпилировал их с конвейером активов. Однако я только что узнал, что "готовое" событие jQuery не срабатывает при последующих щелчках, когда turbo-linking включен. При первой загрузке страницы он работает. Но когда вы нажимаете ссылку, что-нибудь внутри ready( function($) { не будет выполняться (потому что страница не на самом деле загрузить снова). Хорошее объяснение: здесь.
Итак, мой вопрос: Что такое правильный способ, чтобы убедиться, что jQuery события работать должным образом, в то время как турбо-ссылки? Вы обертываете скрипты в слушателе, специфичном для Rails? Или, может быть, у rails есть какая-то магия, которая делает ее ненужной? Документы немного расплывчато о том, как это должно работать, особенно в случае загрузки нескольких файлов через манифест(ы) как приложение.js.
19 ответов:
вот что я делаю... CoffeeScript:
ready = -> ...your coffeescript goes here... $(document).ready(ready) $(document).on('page:load', ready)последняя строка прослушивает загрузку страницы, что и вызовет turbo links.
Edit...добавление версии Javascript (по запросу):
var ready; ready = function() { ...your javascript goes here... }; $(document).ready(ready); $(document).on('page:load', ready);Edit 2...Для Рельсов 5 (Турболин 5)
page:loadстановитсяturbolinks:loadи будет даже уволен при начальной нагрузке. Так что мы можем просто сделать следующее:$(document).on('turbolinks:load', function() { ...your javascript goes here... });
Я только что узнал о другом варианте решения этой проблемы. Если вы загружаете the
jquery-turbolinksgem он будет связывать события Rails Turbolinks сdocument.readyсобытия, так что вы можете написать свой jQuery обычным способом. Вы просто добавляетеjquery.turbolinksсразу послеjqueryв файле манифеста js (по умолчанию:application.js).
недавно я нашел самый чистый и простой способ борьбы с ним:
$(document).on 'ready page:load', -> # Actions to doили
$(document).on('ready page:load', function () { // Actions to do });EDIT
Если у вас есть делегированные события привязанные кdocument, убедитесь, что вы прикрепляете их за пределамиreadyфункция, в противном случае они получат отскок на каждомpage:loadсобытие (вызывающее выполнение одних и тех же функций несколько раз). Например, если у вас есть какие-либо вызовы это:$(document).on 'ready page:load', -> ... $(document).on 'click', '.button', -> ... ...выньте их из
нашел Rails 4 документация, похоже на решение Демозлука, но немного короче:
$(document).on 'page:change', -> # Actions to doили
$(document).on('page:change', function () { // Actions to do });если у вас есть внешние скрипты, которые вызывают
$(document).ready()или если вы не можете быть обеспокоены переписыванием всех существующих JavaScript, то этот драгоценный камень позволяет вам продолжать использовать$(document).ready()С TurboLinks: https://github.com/kossnocorp/jquery.turbolinks
на новый рельсы направляющие, правильный способ сделать следующее:
$(document).on('turbolinks:load', function() { console.log('(document).turbolinks:load') });или, в coffeescript:
$(document).on "turbolinks:load", -> alert "page has loaded!"не слушайте события
$(document).readyи только одно событие будет уволен. Никаких сюрпризов, не нужно использовать jquery.turbolinks камень.это работает с рельсами 4.2 и выше, а не только с рельсами 5.
Примечание: см. ответ @SDP для чистого, встроенного решения
я исправил это следующим образом:
убедитесь, что вы включаете приложений.js до того, как другие зависимые от приложения JS-файлы будут включены, изменив порядок включения следующим образом:
// in application.js - make sure `require_self` comes before `require_tree .` //= require_self //= require_tree .определить глобальную функцию, которая обрабатывает привязку в
application.jsвы можете связать такие вещи, как:// application.js window.onLoad = function(callback) { // binds ready event and turbolink page:load event $(document).ready(callback); $(document).on('page:load',callback); };// in coffee script: onLoad -> $('a.clickable').click => alert('link clicked!'); // equivalent in javascript: onLoad(function() { $('a.clickable').click(function() { alert('link clicked'); });
ничто из вышеперечисленного не работает для меня, я решил это, не используя $(документ) jQuery.готов, но вместо этого используйте addEventListener.
document.addEventListener("turbolinks:load", function() { // do something });
использовать
$(document).on "page:load", attachRatingHandlerили использовать jQuery .на функции для достижения того же эффекта
$(document).on 'click', 'span.star', attachRatingHandlerсмотрите здесь для получения более подробной информации: http://srbiv.github.io/2013/04/06/rails-4-my-first-run-in-with-turbolinks.html
вместо того, чтобы использовать переменную для сохранения функции "ready" и привязки ее к событиям, вы можете вызвать
readyсобытие всякий раз, когдаpage:loadтриггеры.$(document).on('page:load', function() { $(document).trigger('ready'); });
вот что я сделал, чтобы убедиться, что вещи не выполняются дважды:
$(document).on("page:change", function() { // ... init things, just do not bind events ... $(document).off("page:change"); });Я нахожу с помощью
jquery-turbolinksкамень или сочетание$(document).readyи$(document).on("page:load")или через$(document).on("page:change")сам по себе ведет себя неожиданно-особенно если вы находитесь в разработке.
Я нашел следующее статьи который отлично работал для меня и детализирует использование следующего:
var load_this_javascript = function() { // do some things } $(document).ready(load_this_javascript) $(window).bind('page:change', load_this_javascript)
Я решил, что оставлю это здесь для тех, кто обновится до Turbolinks 5: самый простой способ исправить ваш код, чтобы перейти от:
var ready; ready = function() { // Your JS here } $(document).ready(ready); $(document).on('page:load', ready)to:
var ready; ready = function() { // Your JS here } $(document).on('turbolinks:load', ready);Ссылка:https://github.com/turbolinks/turbolinks/issues/9#issuecomment-184717346
вы должны использовать:
document.addEventListener("turbolinks:load", function() { // your code here })
<%= link_to 'Edit', edit_article_path(article), 'data-no-turbolink' => true %>может быть, вы можете использовать, как это, чтобы использовать "готов", это так же, как закрыть ваш turbolink.
во-первых, установить
jquery-turbolinksкамень. И затем, не забудьте переместить включенные файлы Javascript из конца тела вашегоapplication.html.erbв своем<head>.как описано здесь, если вы поместили ссылку javascript приложения в нижний колонтитул по причинам оптимизации скорости, вам нужно будет переместить его в тег, чтобы он загружался перед содержимым в теге. Это решение сработало для меня.
протестировано так много решений, наконец, пришли к этому. Это много ваш код определенно не вызывается дважды.
var has_loaded=false; var ready = function() { if(!has_loaded){ has_loaded=true; // YOURJS here } } $(document).ready(ready); $(document).bind('page:change', ready);
Я обычно делаю следующее Для моих проектов rails 4:
на
application.jsfunction onInit(callback){ $(document).ready(callback); $(document).on('page:load', callback); }затем в остальных .JS файлы, вместо того, чтобы использовать
$(function (){})Я называюonInit(function(){})
Comments