Entendiendo el ciclo de vida del objeto DOM

Hola a todos. Estoy intentando resolver un problema con lo que creo que es el ciclo de vida de los objetos DOM. He leído este hilo A tour of how the Widget (Virtual DOM) code in Discourse works pero todavía no me ayuda a responder mi pregunta, o al menos a señalarme una dirección para intentar resolver mi problema. Me está costando asimilarlo.

He escrito un plugin muy básico como envoltorio para un servicio externo (Rumbletalk chat engine, para ser exactos). El plugin funciona como quiero, el chat funciona, etc., excepto si navegas desde el chat a otra parte de mi sitio y luego vuelves al chat. Recibo un error del javascript que incluyen, que estoy intentando crear un chat duplicado.

El plugin es un simple hbs/widget que crea el siguiente HTML

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

Y tiene algo de javascript de inicio de sesión también.

Supongo que en algún lugar del DOM, el HTML renderizado todavía está presente, y cuando esta etiqueta de script se carga y se ejecuta de nuevo, lo detecta. Cuando depuro en la consola de desarrollo, veo que el error se produce desde el javascript de la etiqueta del script, no del código de inicio de sesión.

Me he puesto en contacto con el personal de Rumbletalk, pero aún no he recibido respuesta. ¿Alguien tiene alguna sugerencia sobre qué puedo mirar a continuación? Lo único que he conseguido hacer es añadir un manejador window.onerror y luego hacer un location.reload(). Obviamente, esta no es una buena solución. ¿Hay alguna forma de “vaciar” los objetos DOM del motor de chat cuando la página pierde el foco?

Gracias por cualquier ayuda.

-=Bob

Hola Bob :wave:

Tu problema va un poco más allá de HTML

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

Este script ejecuta una IIFE, inicializa una instancia y almacena la instancia en el ámbito global. El ámbito global es el mismo para toda la sesión en Discourse porque es una aplicación de página única. Puedes comprobarlo con

console.log(RumbleTalkChat)

Después de que el script se cargue por primera vez. Por lo tanto, RumbleTalkChat["$MY_OTHER_ID"] es lo que el script está reclamando

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

Puedes intentar eliminar esa instancia antes de que el script se cargue de nuevo con algo como esto

delete RumbleTalkChat["$MY_OTHER_ID"]

Ten en cuenta que no contiene el carácter ?.

Dicho esto, probablemente estarás mejor si averiguas por qué el script se carga varias veces en primer lugar. Veo que el script tiene un método openChat() que puedes llamar. Por lo tanto, cargar el script varias veces podría no ser necesario.

Desafortunadamente, necesitarías proporcionar más detalles sobre dónde va la incrustación y cómo estás agregando el marcado antes de que podamos identificar la causa.

4 Me gusta

Hola Joe
Gracias por la explicación del IIFE, asumí que era ALGO así, o, como decía el título, era un objeto con ámbito DOM. También vi la comprobación

if (e.RumbleTalkChat[a.hash]) {
  throw new Error("Intentando crear un chat duplicado con el código: " + a.hash);
}

en el módulo también. Ese módulo se carga con el resto de la página al renderizar el widget. Veré si puedo mover eso posiblemente al inicializador y luego simplemente renderizar el formulario.

¡Gracias de nuevo, adelante y hacia arriba!

2 Me gusta