2017-05-27 16 views
1

ありがとうございます!HTML読み込み順序のクォークをインポートしますか?

HTMLインポートで特定の動作を理解するのに苦労しています。私はちょうど輸入の中で1行を交換し、まったく別の出力を得ています。だからここ

index.htmlを

<!DOCTYPE html> 
<html> 
<head> 
    <link rel="import" href="./element-a.html"> 
    <link rel="import" href="./element-b.html"> 
    <link rel="import" href="./element-c.html"> 
</head> 
<body> 
    <element-a></element-a> 
</body> 
</html> 

要素-a.html

<template> 
    <element-b> 
     <element-c>Hi!</element-c> 
    </element-b> 
</template> 

<script> 
console.log('registering a'); 

class ElementA extends HTMLElement { 
    constructor() { 
     super(); 

     console.log('upgrading a'); 

     const $template = this.constructor.ownerDocument.querySelector('template'); 
     const $clone = $template.content.cloneNode(true); 

     this.attachShadow({ mode: 'open' }); 
     this.shadowRoot.appendChild($clone); 

     const $c = this.shadowRoot.querySelector('element-c'); 
     const isDefined =() => console[$c.say ? 'debug' : 'error'](`say() is ${$c.say ? '': 'un'}defined`) 

     isDefined(); 

     const undefined = this.shadowRoot.querySelectorAll(':not(:defined)'); 
     const promises = [...undefined].map(el => customElements.whenDefined(el.localName)); 

     console.log('undefined: ', undefined); 

     Promise.all(promises).then(() => { 
      console.log('ready'); 
      isDefined(); 
     }); 
    } 
} 

ElementA.ownerDocument = document.currentScript.ownerDocument; 

customElements.define('element-a', ElementA); 
</script> 

要素-b.html

...私が得たものです
<template> 
    <slot></slot> 
</template> 

<script> 
console.log('registering b'); 

class ElementB extends HTMLElement { 
    constructor() { 
     super(); 

     console.log('upgrading b'); 

     const $template = this.constructor.ownerDocument.querySelector('template'); 
     const $clone = $template.content.cloneNode(true); 

     this.attachShadow({ mode: 'open' }); 
     this.shadowRoot.appendChild($clone); 
    } 
} 

ElementB.ownerDocument = document.currentScript.ownerDocument; 

customElements.define('element-b', ElementB); 
</script> 

要素-c.html

<template> 
    <slot></slot> 
</template> 

<script> 
console.log('registering c'); 

class ElementC extends HTMLElement { 
    constructor() { 
     super(); 

     console.log('upgrading c'); 

     const $template = this.constructor.ownerDocument.querySelector('template'); 
     const $clone = $template.content.cloneNode(true); 

     this.attachShadow({ mode: 'open' }); 
     this.shadowRoot.appendChild($clone); 
    } 

    say(words) { 
     console.log(words); 
    } 
} 

ElementC.ownerDocument = document.currentScript.ownerDocument; 

customElements.define('element-c', ElementC); 
</script> 

私もpenを作成しました。今、私を混乱させているもの:私はelement-a最初をインポートする場合、私はこの出力を得る:
をアップグレード
を登録

は(言う)未定義
定義されていません。(2)[要素-B、エレメント(L) C]
登録B
アップグレードB
登録C
アップグレードC
準備
()は言う

を定義している。しかし、私は最後にそれをインポートする場合、私はをアップグレードとを登録する全く別の出力および順序を取得します。
アップグレードC

アップグレードBをアップグレード
登録C
登録B
登録

は(言う)
未定義定義される:[]
準備
は(と言う)であります定義済み

なぜですか?私は最終的な出力がいつも起こることを期待しています。それはSlotting/Shadow DOMと関係がありますか?

+0

詳細を読むことができます:アップグレードが唯一のドキュメントツリー内の要素に適用されることに注意してください。ドキュメントに挿入されていない要素はアップグレードされないままです。したがって、2番目の例では、 "A"がまだドキュメントにないため、すべてが最初に登録されます。 – ebidel

+0

私は理解していますが、私は輸入の順序がそれと関係しているものを得ていませんか?特に 'element-a'は、両方の場合において常に最初からドキュメントツリーに存在するからです。 – mzdr

+1

'element-a'は最初からドキュメントにありますが、' b'と 'c'は(' a'が登録されるまで)ありません。これらの2人は、輸入品を読み込んでいるb/cにすぐに登録されます。 'a'のインポートがそれらをドキュメントに追加するまではアップグレードされません。理にかなっている? – ebidel

答えて

1

element-a.html内のelement-aの依存関係をインポートする必要があります。 HTMLImportはコンポーネントをインポートして登録します。そのため、他のファイルをインポートする前にコンポーネントを登録する(インポートは非​​同期です)ため、未定義の情報が得られます。要素内の依存関係をインポートすると、ブラウザはコンポーネントを登録する前にすべての依存関係が完了するまで待機します。

あなたはhttps://w3c.github.io/webcomponents/spec/custom/#upgradesからManaging dependencies and sub-imports

+2

デポを必要とするコンポーネントのインポート内でdepsを管理してください。ただし、インポートはデフォルトでは非同期ではなく、ブラウザは要素を登録する前にすべての読み込みがロードされるまで待機しません。私はそれがポリマー1.0のものだと信じています。 – ebidel

関連する問題