Если ваши встроенные сценарии включены внизу <body>
(или если они не сразу манипулируют DOM), то вы можете удалить свой код из функции $(document).ready…
и заставить их работатькак и ожидалось.
Встроенные сценарии, как правило, не рекомендуется, поскольку традиционно они указывают, что код будет выполняться только на той странице, на которой он включен, и что любые прослушиватели событий будут автоматически уничтожены, когда пользователь уйдет.Однако в приложениях Turbolinks это не так.Если вы добавите прослушиватель событий во встроенный скрипт (и не удаляете его), он продолжит прослушивание и запуск при последующих загрузках страницы.Как вы выяснили, настроив прослушиватель событий turbolinks:load
таким образом, обработчик сработал при последующих загрузках страниц и при повторном посещении первой страницы прослушиватель событий был добавлен снова, что привело к дублированию вызовов.
Относительнонастраивая «состояние JavaScript для каждой страницы» и «загрузочные модели на стороне клиента», скажем, у вас есть страница календаря, которую вы хотите улучшить с помощью некоторого JavaScript.Возможно, у вас есть Calendar
класс JavaScript, который обрабатывает это, поэтому вы можете включить следующее, чтобы загрузить его с некоторым JSON:
<script>new Calendar(<%= @calendar.to_json %>)</script>
(имея в виду, что все добавленные прослушиватели событий настроены в Calender
класс, вероятно, должен быть уничтожен в какой-то момент, например turbolinks:before-cache
).
Это демонстрирует идею, но лучшим подходом в этом случае может быть установка системы, которая ищет элементы календаря, а затем в DOMсоздает ихНапример:
<div data-component="calendar" data-props="<%= @calendar.to_json %>">…</div>
затем в вашем JavaScript (входит в комплект приложения):
;(function () {
var calendar
$(document).on('turbolinks:load', function () {
var $el = $('[data-component=calendar]')
if ($el.length) calendar = new Calender($el.data('props'))
})
$(document).on('turbolinks:before-cache', function () {
if (calendar) {
calendar.destroy() // to teardown any event listeners etc
calender = null
}
})
})()
Этот подход можно обобщить, и я рассмотрел одну реализацию здесь: https://stackoverflow.com/a/44057187/783009
Надеюсь, это поможет!