DOMオブジェクトのライフサイクルを理解する

皆さん、こんにちは。DOM オブジェクトのライフサイクルに関する問題について、皆さんの知恵を借りたいと思います。このスレッド A tour of how the Widget (Virtual DOM) code in Discourse works を読みましたが、私の質問に答えたり、問題を解決するための方向性を示してくれたりするものではありませんでした。どうにも理解できないのです。

外部サービス(具体的には Rumbletalk チャットエンジン)のラッパーとして、非常に基本的なプラグインを作成しました。プラグインは期待どおりに動作し、チャットも機能していますが、チャットからサイトの別の部分に移動してからチャットに戻ると問題が発生します。その際、彼らが提供している JavaScript から、重複したチャットを作成しようとしているというエラーが発生します。

プラグインは、次の HTML を生成するシンプルな HBS/ウィジェットです。

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

また、ログイン用の JavaScript も含まれています。

レンダリングされた HTML が DOM にまだ残っており、このスクリプトタグが再度読み込まれて実行されると、それが検出されるのだと推測しています。開発者コンソールのデバッグでは、ログインコードではなく、スクリプトタグからの JavaScript でエラーが発生していることが確認できます。

Rumbletalk のサポートに連絡しましたが、まだ返信がありません。次に何を調べるべきか、何か提案はありますか? 私ができたことは、window.onerror ハンドラーを追加して location.reload() を実行することだけです。これは明らかに良い解決策ではありません。ページがフォーカスを外れたときに、チャットエンジンの DOM オブジェクトを「フラッシュ」する方法はありますか?

何か助けがあれば幸いです。

-=Bob

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() というメソッドがあり、それを呼び出すことができるようです。そのため、スクリプトを複数回ロードする必要はないかもしれません。

残念ながら、埋め込みがどこに行われ、マークアップをどのように追加しているかについて、もう少し詳細を提供していただけないと、原因を特定することはできません。

「いいね!」 4

こんにちは、ジョーさん
IIFE の説明ありがとうございます。その種の何かだろう、あるいはタイトルにあったように、DOM スコープのオブジェクトだろうと推測していました。モジュール内で以下のチェックも確認しました。

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

そのモジュールは、ウィジェットのレンダリング時に他のページコンテンツと共にロードされます。それを初期化処理に移動し、フォームのみをレンダリングできるか確認してみます。

重ねてお礼申し上げます。前進あるのみです!

「いいね!」 2