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>
いくつかの試み:
- ドキュメント フラグメント内 - this、self、window、および document はすべて親ウィンドウを参照します。そして、誰もシャドウ ルートにアクセスできません。
- グローバル変数にシャドウ ルートを格納し、フラグメントまたは 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>
同様の質問 ( 25048359、16633057、55101967など) に関する注意 - モードが閉じている場合、これらの回答は機能しません。