Понимание жизненного цикла объекта DOM

Привет, друзья. Пытаюсь разобраться с проблемой, связанной, как мне кажется, с жизненным циклом объектов DOM. Я прочитал эту тему: A tour of how the Widget (Virtual DOM) code in Discourse works, но она всё ещё не помогает ответить на мой вопрос или хотя бы указать направление для решения проблемы. Мне трудно в этом разобраться.

Я написал очень простой плагин-обёртку для внешнего сервиса (а именно, для чат-движка Rumbletalk). Плагин работает так, как я ожидал: чат функционирует и так далее, за исключением случая, когда вы переходите от чата к другой части моего сайта, а затем возвращаетесь обратно. В этом случае я получаю ошибку от их встроенного JavaScript-кода, сообщающую о попытке создать дубликат чата.

Плагин представляет собой простой hbs-виджет, который генерирует следующий HTML:

<div style="height: 500px;">
  <div id="$MY_ID"></div>
  <script src="https://rumbletalk.com/client/?$MY_OTHER_ID"></script>
</div>

Также в нём есть немного JavaScript-кода для входа.

Я предполагаю, что где-то в DOM отрисованный HTML всё ещё остаётся, и когда этот тег загружается и выполняется снова, он это обнаруживает. При отладке в консоли разработчика я вижу, что ошибка выбрасывается именно JavaScript-кодом из тега , а не из кода входа.

Я уже обращался к сотрудникам Rumbletalk, но пока не получил ответа. Есть ли у кого-нибудь идея, на что мне стоит посмотреть дальше? Единственное, что мне удалось сделать, — это добавить обработчик window.onerror и затем выполнить location.reload(). Очевидно, это не лучшее решение. Есть ли способ «очистить» объекты DOM чат-движка, когда страница теряет фокус?

Спасибо за любую помощь.

-=Bob

Привет, Боб :wave:

Твоя проблема немного выходит за рамки HTML.

<script src="https://rumbletalk.com/client/?$MY_OTHER_ID"></script>

Этот скрипт запускает IIFE, инициализирует экземпляр и сохраняет его в глобальной области видимости. Глобальная область видимости в Discourse одинакова для всей сессии, так как это одностраничное приложение. Ты можешь проверить это с помощью

console.log(RumbleTalkChat)

после первой загрузки скрипта. Таким образом, именно RumbleTalkChat["$MY_OTHER_ID"] вызывает ошибку в скрипте:

if (e.RumbleTalkChat[a.hash]) {
  throw new Error("Trying to create a duplicate chat with code: " + a.hash);
}

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

delete RumbleTalkChat["$MY_OTHER_ID"]

Обрати внимание, что в ключ не входит символ ?.

Тем не менее, тебе, скорее всего, будет лучше, если ты выяснишь, почему скрипт загружается несколько раз. Я вижу, что у скрипта есть метод openChat(), который можно вызывать. Возможно, многократная загрузка скрипта вовсе не требуется.

К сожалению, чтобы точно определить причину, нам нужно больше информации о том, куда именно вставляется код встраивания и как ты добавляешь разметку.

Привет, Джо!
Спасибо за объяснение IIFE. Я предполагал, что это что-то вроде этого, или, как сказано в заголовке, объект с областью видимости DOM. Я также заметил проверку

if (e.RumbleTalkChat[a.hash]) {
  throw new Error("Trying to create a duplicate chat with code: " + a.hash);
}

в модуле. Этот модуль загружается вместе с остальной частью страницы при рендеринге виджета. Я попробую, возможно, переместить это в инициализатор, а затем просто отрендерить форму.

Спасибо ещё раз, вперёд и только вверх!