Den Lebenszyklus von DOM-Objekten verstehen

Hallo Leute. Ich versuche, ein Problem mit dem DOM-Objektlebenszyklus zu lösen. Ich habe diesen Thread gelesen: A tour of how the Widget (Virtual DOM) code in Discourse works, aber er hilft mir immer noch nicht, meine Frage zu beantworten oder mich zumindest in eine Richtung zu weisen, um mein Problem zu lösen. Ich habe Schwierigkeiten, es zu verstehen.

Ich habe ein sehr einfaches Plugin als Wrapper für einen externen Dienst (genauer gesagt, die Rumbletalk-Chat-Engine) geschrieben. Das Plugin funktioniert wie gewünscht, der Chat funktioniert usw., außer wenn Sie vom Chat zu einem anderen Teil meiner Website navigieren und dann zurück zum Chat. Ich erhalte einen Fehler aus deren mitgeliefertem JavaScript, dass ich versuche, einen doppelten Chat zu erstellen.

Das Plugin ist ein einfaches hbs/Widget, das den folgenden HTML-Code erstellt:

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

Und hat auch einige Anmelde-JavaScript.

Ich gehe davon aus, dass irgendwo im DOM noch das gerenderte HTML vorhanden ist und wenn dieses Skript erneut geladen und ausgeführt wird, wird es erkannt. Wenn ich in der Entwicklerkonsole debugge, sehe ich den Fehler, der aus dem JavaScript des Skript-Tags und nicht aus dem Anmeldecode ausgelöst wird.

Ich habe mich an das Personal von Rumbletalk gewandt, aber noch keine Antwort erhalten. Hat jemand einen Vorschlag, was ich als Nächstes untersuchen kann? Das Einzige, was mir gelungen ist, ist das Hinzufügen eines window.onerror-Handlers und dann ein location.reload(). Das ist offensichtlich keine gute Lösung. Gibt es eine Möglichkeit, die DOM-Objekte der Chat-Engine zu “leeren”, wenn die Seite den Fokus verliert?

Vielen Dank für jede Hilfe.

-=Bob

Hallo Bob :wave:

Dein Problem geht ein wenig über HTML hinaus

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

Dieses Skript führt eine IIFE aus, initialisiert eine Instanz und speichert die Instanz im globalen Geltungsbereich. Der globale Geltungsbereich ist für die gesamte Sitzung in Discourse gleich, da es sich um eine Single-Page-Anwendung handelt. Du kannst das mit

console.log(RumbleTalkChat)

überprüfen, nachdem das Skript zum ersten Mal geladen wurde. Daher beschwert sich das Skript über RumbleTalkChat["$MY_OTHER_ID"]

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

Du kannst versuchen, diese Instanz zu entfernen, bevor das Skript erneut geladen wird, mit etwas wie diesem

delete RumbleTalkChat["$MY_OTHER_ID"]

Beachte, dass es das Zeichen ? nicht enthält.

Davon abgesehen ist es wahrscheinlich besser, wenn du herausfindest, warum das Skript überhaupt mehrmals geladen wird. Ich sehe, dass das Skript eine openChat()-Methode hat, die du aufrufen kannst. Das mehrmalige Laden des Skripts ist daher möglicherweise nicht notwendig.

Leider müsstest du mehr Details darüber angeben, wo das Embed platziert wird und wie du das Markup hinzufügst, damit wir die Ursache ermitteln können.

4 „Gefällt mir“

Hallo Joe
Danke für die Erklärung des IIFE, ich habe angenommen, dass es SO ETWAS ist, oder, wie der Titel sagte, ein DOM-bezogenes Objekt war. Ich habe die Prüfung gesehen

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

auch im Modul. Dieses Modul wird mit dem Rest der Seite beim Rendern des Widgets geladen. Ich werde sehen, ob ich das möglicherweise in den Initialisierer verschieben und dann nur das Formular rendern kann.

Danke nochmals, vorwärts und aufwärts!

2 „Gefällt mir“