Скрипты на JavaScript, нацеленные на подвал, не работают после переходов между страницами

Я написал CSS-код, чтобы сделать меню в подвале адаптивным. При переходе на мобильные устройства меню в подвале отображается аналогично гамбургер-меню. Я добавил функцию обработки клика в секцию Edit CSS/HTML >> /head, чтобы переключать меню в мобильном режиме.

Здесь функция клика работала корректно на главной странице Discourse. Однако на некоторых других страницах, таких как Summary, Forum Account и т. д., скрипт блокировался. Поэтому я не могу увидеть подменю. При этом в исходном коде браузера скрипт отображается.

Почему выполнение пользовательских скриптов блокируется на некоторых страницах в Discourse? Какое постоянное решение этой проблемы?

Discourse — это одностраничное приложение. Поэтому скрипты, которые вы добавляете в тег <head>, выполняются только один раз при первоначальной загрузке страницы, если не используются соответствующие хуки. Скорее всего, вам нужно доработать ваш код и добавить обработчик событий.

Можете ли вы поделиться вашим кодом?

Вот мой скрипт,

Скорее всего, есть несколько способов решить эту проблему, но давайте попробуем «правильный» подход, используя соответствующие хуки кастомизации.

Когда вы добавляете HTML в секцию подвала темы, Discourse выполняет специальную обработку, чтобы элементы не «прыгали» при переходах между страницами или при добавлении новых элементов с помощью бесконечной прокрутки.

Этот контент добавляется как компонент custom-html здесь:

discourse/app/assets/javascripts/discourse/app/templates/application.hbs at a0bbc346cb5d5b89d1a3efdfa89869349a8b067f · discourse/discourse · GitHub

Если вы посмотрите на код компонента, то увидите, что при его рендеринге генерируется событие приложения.

discourse/app/assets/javascripts/discourse/app/components/custom-html.js at a0bbc346cb5d5b89d1a3efdfa89869349a8b067f · discourse/discourse · GitHub

Именно этот хук вам нужно использовать.

Как его использовать?
В plugin-api есть метод, позволяющий выполнять код при срабатывании определённого события приложения.

https://github.com/discourse/discourse/blob/master/app/assets/javascripts/discourse/app/lib/plugin-api.js#L507-L519

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

api.onAppEvent("inserted-custom-html:footer", () => {
  // выполните здесь необходимые действия
});

Поскольку это метод plugin-API, вам нужно изменить тип тега скрипта на text/discourse-plugin так:

<script type="text/discourse-plugin" version="0.8">
api.onAppEvent("inserted-custom-html:footer", () => {
  // выполните здесь необходимые действия
});
</script>

Приведённый выше фрагмент будет выполняться каждый раз при рендеринге подвала. Теперь вы можете сделать что-то вроде этого:

<script type="text/discourse-plugin" version="0.8">
api.onAppEvent("inserted-custom-html:footer", () => {
  $(".footer-div #footerNavDiv").click(function () {
    console.log("событие клика перехвачено");
    // выполните здесь необходимые действия для события клика
  });
});
</script>

Подробнее о plugin-API можно прочитать здесь

Отлично, спасибо :slight_smile: