4

Web コンポーネントを作成しましたが、コンポーネント内から要素にアクセスしたいと考えています。
.attachMode({mode:'closed'}) を使用しているため、親はアクセスできません。

<template id='hello-world-template'>
  <span id='inside'>Unchanged,</span> <span id='outside'>Unchanged</span>
  <script>
    document.querySelector('#inside').innerHTML = 'Changed';
    // Ideal, but does not work - no such element 
  </script>
</template>
<hello-world></hello-world>

<script>
customElements.define('hello-world',
   class extends HTMLElement {
      constructor() {
         super();
         var template = document.getElementById('hello-world-template')
         var clone = template.content.cloneNode(true)
         const shadowRoot = this.attachShadow({mode: 'closed'}).appendChild(clone);
         }
      connectedCallback() {
        this.shadowRoot.querySelector('#outside').innerHTML = 'Changed';
        // Not ideal, and also does not work - this.shadowRoot has no querySelector
        }
      });
</script>

いくつかの試み:

  1. ドキュメント フラグメント内 - this、self、window、および document はすべて親ウィンドウを参照します。そして、誰もシャドウ ルートにアクセスできません。
  2. グローバル変数にシャドウ ルートを格納し、フラグメントまたは connectedCallback 内からアクセスしようとしました。
    それが機能したとしても、{mode:'closed'} を使用するポイントが無効になりますが、とにかく機能しませんでした。

機能するハックがありますが、それを使用する必要があるとは想像できません。
カプセル化の要点は、物事を自己完結できるということですが、JS がコンテナー内の他の項目に作用できない場合、それは何の役に立つでしょうか?

これが解決策である場合は、コンポーネントの実装方法のロジックを説明するヒントが欲しいです。
ただし、ハックは次のとおりです。JS オンロードを実行するイメージを含めます。

<template id='hello-world-template'>
  <span id='inside'>Unchanged,</span> <span id='outside'>Unchanged</span>
  <script>
    function runner(img){
       let doc = img.parentNode;
       doc.querySelector('#inside').innerHTML = 'Changed';
       }
  </script>
  <img src='data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=' onload="runner(this)">
</template>
<hello-world></hello-world>

同様の質問 ( 250483591663305755101967など) に関する注意 - モードが閉じている場合、これらの回答は機能しません。

4

1 に答える 1