Как обойти DOMContentLoaded для навигации?

У нас есть JS-функция, которая выполняется при событии DOMContentLoaded: document.addEventListener(“DOMContentLoaded”, OURFUNCTION).

Это работает корректно при перезагрузке страницы, но не срабатывает при навигации по сайту. Я предполагаю, что это связано с тем, что Discourse загружает DOM только один раз, а дальнейшая навигация обрабатывается на стороне клиента, как в SPA. Поэтому меня интересует, как можно запускать эту функцию при изменении маршрута в самом Discourse? Раньше для этого были простые способы через API плагинов, но эти API устарели, и я больше не вижу их использования в компонентах. Есть ли простой способ сделать это сейчас? Или нам нужно создавать целый компонент только для выполнения JavaScript при смене навигации? Спасибо.

Привет,

Если вы ищете событие, срабатывающее при загрузке страницы, обратите внимание на api.onPageChange.

api.onPageChange((url, title) => {
   console.log('страница изменилась на: ' + url + ' и заголовок ' + title);
});

Если вы имели в виду что-то другое, пожалуйста, уточните, чего именно вы хотите добиться. Мы сможем дать более точный ответ.

Кстати, у нас есть множество документов, которые могут вам пригодиться: Developer Guides - Discourse Meta.

Хм… Я не уверен, что это гарантирует загрузку содержимого DOM. Мне кажется, это событие срабатывает при смене маршрута, что происходит гораздо раньше.

Если загрузка DOM важна, вам стоит рассмотреть возможность прикрепления компонента к плагину-разъему и срабатывания модификатора didInsert.

Если же важно только изменение маршрута, то да, onPageChange должно сработать :+1:

Возможно, вы правы! :thinking:

onPageChange вызывается в следующем цикле выполнения, поэтому, думаю, в большинстве случаев он всё равно будет вызван после DOMContentLoaded, но я не могу гарантировать это на 100%.

Я вижу случаи использования, когда полагаются на onPageChange и сразу работают с элементами DOM. Кстати, откуда именно генерируется событие routeDidChange (РЕДАКТИРОВАНО: из Ember: RouterService | 6.11.0 | Ember API Documentation)?

Согласен с модификатором didInsert, действительно здорово!

Спасибо. Я внимательно изучил документацию и, судя по моим комментариям и последующему ответу участника на форуме Discourse, API плагина устарело и скоро будет отключено. Поэтому, хотя ваш код сейчас может работать, он скоро перестанет функционировать, вероятно, в будущих обновлениях. Вот почему я ищу лучшее решение. Создавать компонент Glimmer для этой задачи кажется излишним, поэтому я надеялся, что есть какое-то другое событие, которое мы могли бы использовать.

Я не думаю, что это верно.

был обновлён на прошлой неделе.

Что выводится из употребления:

  • API виджетов
  • Сырые шаблоны
  • Переопределение шаблонов в целом

Спасибо за уточнение! Значит, дело только в API виджета. Хорошо, сначала попробую предложенные выше варианты работы с API.

Это скорее благословение :sweat_smile:, Glimmer гораздо удобнее для разработчиков.

Кстати, мы протестировали это с помощью api.OnPageChange, и всё работает отлично. У нас пока не было случаев, когда содержимое DOM не было доступно при вызове OnPageChange, поэтому кажется, что событие срабатывает после DomContentLoaded. Но я не могу быть уверен на 100%. Спасибо за помощь в этом вопросе.

Хорошо. Просто имейте в виду, что сроки не гарантируются. Но я рад, что это подходит для вашего случая использования!

Не могли бы вы пояснить, что это означает? Что такое модификатор didInsert? У меня срабатывает событие decorateCookedElement. Спасибо.

Документация — лучший вариант, как отметил Роберт; вы также можете найти множество примеров в репозитории: Code search results · GitHub

О, понял, так это функция Ember и не связана с Discourse? Единственная часть в коде, которая действительно относится к «Discourse» — это pluginOutlet?

Да, это часть стандарта Glimmer

pluginOutlets — это просто специальные компоненты, предназначенные для монтирования других компонентов: