2017-03-06 4 views
3

シャドウDOM(V1)例in this tutorialを通って行く、各タブは、名前、デフォルトスロットに対応することは、Webコンポーネント(タブ)を定義:間に中間要素がある場合は、影付きDOMコンテンツを挿入することはできますか?

<fancy-tabs> 
    <button slot="title">Title</button> 
    <button slot="title" selected>Title 2</button> 
    <button slot="title">Title 3</button> 
    <section>content panel 1</section> 
    <section>content panel 2</section> 
    <section>content panel 3</section> 
</fancy-tabs> 

そして、それはこれにレンダリングするであろう:

<fancy-tabs> 
    #shadow-root 
    <div id="tabs"> 
     <slot id="tabsSlot" name="title"> 
     <button slot="title">Title</button> 
     <button slot="title" selected>Title 2</button> 
     <button slot="title">Title 3</button> 
     </slot> 
    </div> 
    <div id="panels"> 
     <slot id="panelsSlot"> 
     <section>content panel 1</section> 
     <section>content panel 2</section> 
     <section>content panel 3</section> 
     </slot> 
    </div> 
</fancy-tabs> 

既存のAPIを保持するために、私はこのようなコンポーネントを作成したいと思いますが、各タブを独自のカスタム要素として作成することができます。したがって、次のようなAPI:

<fancy-tabs> 
    <fancy-tab> 
    <button slot="title">Title</button> 
    <section>content panel 1</section> 
    </fancy-tab> 
    <fancy-tab> 
    <button slot="title" selected>Title 2</button> 
    <section>content panel 2</section> 
    <fancy-tab> 
    <fancy-tab> 
    <button slot="title" selected>Title 3</button> 
    <section>content panel 3</section> 
    <fancy-tab> 
</fancy-tabs> 

しかし、それは上記のようなシャドーDOMにレンダリングされます。

つまり、私は、<fancy-tab>のような中間要素を持っていて、その下のスロット要素を制御しています。私はシャドウルートを持たないCEとして、シャドウルートを開いてCEとして<fancy-tab>を作成しようとしましたが、カスタムエレメントとして定義していません。

これを行う方法はありますか?またはスロットがLight DOMの最初の子であるとしますか?

答えて

1

slot属性を持つ要素は、Light DOMの最初の子でなければなりません。

したがって、3番目のコードの構造を保持したい場合は、それぞれシャドウDOMを持つnested custom elementsを使用できます。

<fancy-tabs>コンポーネントは、<fancy-tab>を取得します。 <fancy-tab>コンポーネントがコンテンツを取得します。実際には(当然のカスタマイズのニーズのためではなく、することができます)あなたもシャドウDOMのサブコンポーネントを定義する必要はありません「タブ」コンポーネントを作成するための


ここでは、最小限の<fancy-tabs>カスタム要素の例です:

customElements.define('fancy-tabs', class extends HTMLElement 
 
{ 
 
    constructor() 
 
    { 
 
     super() 
 
     this.btns = this.querySelectorAll('button ') 
 
     this.addEventListener('click', this) 
 
     this.querySelector('button[selected]').focus() 
 
    } 
 

 
    handleEvent(ev) 
 
    { 
 
     this.btns.forEach(b => 
 
     { 
 
      if (b === ev.target) 
 
       b.setAttribute('selected', true) 
 
      else 
 
       b.removeAttribute('selected') 
 
     }) 
 
    } 
 
})
fancy-tabs { 
 
    position: relative ; 
 
} 
 

 
fancy-tab > button { 
 
    border: none ; 
 
} 
 

 
fancy-tab > section { 
 
    background: #eee ; 
 
    display: none ; 
 
    position: absolute ; left: 0 ; top: 20px ; 
 
    width: 300px ; height: 75px ; 
 
} 
 

 
fancy-tab > button[selected] + section { 
 
    display: inline-block ; 
 
}
<fancy-tabs> 
 
    <fancy-tab> 
 
     <button>Title 1</button> 
 
     <section>content panel 1</section> 
 
    </fancy-tab> 
 
    <fancy-tab> 
 
     <button selected>Title 2</button> 
 
     <section>content panel 2</section> 
 
    </fancy-tab> 
 
    <fancy-tab> 
 
     <button>Title 3</button> 
 
     <section>content panel 3</section> 
 
    </fancy-tab> 
 
</fancy-tabs>

関連する問題