8

2 つのカスタム要素 (v1) を含む Web コンポーネントを使用して、1 つの要素が別の要素にネストされている簡単な例を作成しました。index.html:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Example</title>
  <meta name="description" content="">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="import" href="app-container.html">
</head>
<body>
  <app-container></app-container>
</body>
</html>

app-container.html:

<link rel="import" href="toolbar.html">
<template id="app-container">
  <app-toolbar></app-toolbar>
</template>
<script>
  customElements.define('app-container', class extends HTMLElement {
    constructor() {
      super();
      let shadowRoot = this.attachShadow({ mode: 'open' });
      const content = document.currentScript.ownerDocument.querySelector('#app-container').content;
      shadowRoot.appendChild(content.cloneNode(true));
    }
  });
</script>

ツールバー.html:

<template id="app-toolbar">
  <p>Ok!</p>
</template>
<script>
  customElements.define('app-toolbar', class extends HTMLElement {
    constructor() {
      super();
      let shadowRoot = this.attachShadow({ mode: 'open' });
      const content = document.currentScript.ownerDocument.querySelector('#app-toolbar').content;
      shadowRoot.appendChild(content.cloneNode(true));
    }
  });
</script>

しかし、toolbar.htmldocument.currentScriptは app-container.html と同じであるためquerySelector('#app-toolbar')、id のテンプレートが見つかりませんapp-toolbar。この問題を解決するには?

Chrome 55 でテストされた例 (ポリフィルなし)。

4

1 に答える 1

18

document.currentScript現在解析および実行されているスクリプトへの参照が含まれています。constructor()したがって、関数が(別のスクリプトから)呼び出されると、目的に対して無効になります 。

代わりに、スクリプトの先頭でその値を変数に保存し、コンストラクターでこの変数を使用する必要があります。

<script>
    var currentScript = document.currentScript
    customElements.define( ... )
    ...
</script>

複数のスクリプトがある場合は、個別の名前を使用する必要があります。

別の方法として、一時的な値をクロージャにカプセル化することもできます。

(function(owner) {
    customElements.define('app-container', class extends HTMLElement {
        constructor() {
           super();
           let shadowRoot = this.attachShadow({ mode: 'open' });
           const content = owner.querySelector('#app-container').content;
           shadowRoot.appendChild(content.cloneNode(true));
        }
    });
})(document.currentScript.ownerDocument);

ここで値は、呼び出されたときにまだ正しく定義されている引数にdocument.currentScript.ownerDocument割り当てられます。ownerconstructor()

ownerローカルに定義されているため、他のドキュメントで同じ名前を使用できます。

于 2016-12-31T14:53:38.580 に答える