HTML5 ShadowDOM & CustomElements

11940 ワード

Webコンポーネントは4つの部分から構成されています
  • Template
  • Shadow DOM(Chrome Operaサポート)
  • Custom Elements
  • Packaging

  • Shadow DOM構成Shadow DOMは、Shadow rootと呼ばれる要素がレンダリングされず、Shadow DOMがレンダリングされるルートノードShadow Hostと関連付けることができる.
    ただし、コンテンツはShadow root内に入れるべきではなく、Shadow DOM 等にアクセスされるように、再利用可能な部品の無意味なマークは 内に入れるべきである
    ショーから詳細を分離
    内容はドキュメント内にあります.Shadow DOMに展示されています.更新が必要な場合、ブラウザは自動的に同期を維持します.
    
    
    
      var shadow = document.querySelector('#nameTag').createShadowRoot();
      var template = document.querySelector('#nameTagTemplate');
      var clone = document.importNode(template.content, true);
      shadow.appendChild(clone);
      document.querySelector("#nameTag").textContent = "Shellie"
    
    

    通过select特性, 可以使用多个元素并控制投射元素

    
    
    Bob
    B. Love

    Shadow DOMスタイルShadow DOM定義のShadow DOMスタイルはCSSでのみ有効であり、スタイルはカプセル化されている.
    ホスト要素のスタイル化(host element)Shadow Root:host要素を様式化し、Shadow DOM以外の要素に影響を及ぼさない
    :host(x-bar:host) {
      /*            。 */
    }
    :host(.different:host) {
      /*           。 */
    }
    :host:hover {
      /*             。 */
      opacity: 1;
    }
    

    ^(Hat)と^^(Cat)セレクタShadow DOMコネクタは、子孫セレクタ(例えばdiv p{...})に等価であり、ただshadowの境界を越えることができます.^子孫セレクタは、任意の数のshadow境界を越えることができる.^^はこのセレクタをサポートする
    生HTMLコントロールはshadowdomでスタイル化できます
    video ^ input[type="range"] {
      background: hotpink;
    }
    

    挿入点リセットスタイル
    var root = document.querySelector('div').createShadowRoot();
    root.resetStyleInheritance = false;
    
    {
      reset-style-inheritance: true;
    }
    

    「挿入点」で、親スタイルを継承するかどうかを選択します(継承可能なスタイルにのみ影響します).
    ::content擬似要素挿入点を通ってスタイルを指定する

    Light DOM

    I'm not underlined

    I'm underlined in Shadow DOM!

    var div = document.querySelector('div'); var root = div.createShadowRoot(); root.innerHTML = '\ <style>\ h3 { color: red; }\ content[select="h3"]::content > h3 {\ color: green;\ }\ ::content section p {\ text-decoration: underline;\ }\ </style>\ <h3>Shadow DOM</h3>\ <content select="h3"></content>\ <content select="section"></content>';

    ShadowRootまたはquerySelector()挿入ポイント:reset-style-inheritanceは、継承可能なCSS属性がホスト要素でinitialに設定されていることを意味し、shadowのコンテンツには有効ではありません.この位置を上境界(upper boundary)と呼ぶ.挿入点の場合:reset-style-inheritanceは、ホストのサブエレメントが挿入点に配布される前に、継承可能なCSSプロパティをinitialに設定することを意味します.この位置を下境界(lower boundary)と呼ぶ.
    複数shadowdomの使用
    最近追加されたツリーをyounger treeと呼びます.以前に追加したツリーをolder treeと呼びます.
    ホスト要素に追加されたshadowツリーは、最初に追加されたshadowツリーからスタックされます.最終的にレンダリングされるのは、最後に追加されたshadowツリーです.
    1つのshadowツリーにの挿入点が複数存在する場合、最初の1つだけが確認され、残りは無視される.
    「Shadow挿入点」()はプレースホルダとしてShadowDOM通常挿入点()を挿入できます.プレースホルダとして通常DOM要素を挿入できます.
    要素がShadow DOMを管理している場合は、を使用して.shadowRootにアクセスできます.
    他の人があなたのshadowを動かしたくないなら、それは.shadowRoot再定義null:
    Object.defineProperty(host, 'shadowRoot', {
      get: function() { return null; },
      set: function(value) { }
    });
    

    JSでshadowdomを構築する
    HTML ContentElementおよびHTML ShadowElementインタフェースを使用できます.挿入ポイントを使用してホスト要素から選択してshadowツリーに配布youngest shadow rootのDOMを巡回できません.では、挿入ポイントの分散ノードを問い合わせることができます.

    Eric

    Bidelman

    Digital Jedi

    footer text

    var container = document.querySelector('#example4'); var root = container.createShadowRoot(); var t = document.querySelector('#sdom'); var clone = document.importNode(t.content, true); root.appendChild(clone); var html = []; [].forEach.call(root.querySelectorAll('content'), function(el) { html.push(el.outerHTML + ': '); var nodes = el.getDistributedNodes(); [].forEach.call(nodes, function(node) { html.push(node.outerHTML); }); html.push('
    '); });

    分散ノードで.getDistributedNodes()を使用して、どの挿入ポイントに配布されたかを確認できます.

    Light DOM

    var container = document.querySelector('div'); var root1 = container.createShadowRoot(); var root2 = container.createShadowRoot(); root1.innerHTML = '<content select="h2"></content>'; root2.innerHTML = '<shadow></shadow>'; var h2 = document.querySelector('#host h2'); var insertionPoints = h2.getDestinationInsertionPoints(); [].forEach.call(insertionPoints, function(contentEl) { console.log(contentEl); });

    Shadow DOMビジュアルレンダリングツールShadow DOMビジュアルレンダリングツール:Shadow DOM Visualizer
    shadowdomイベントモデル
    イベントは、Shadow DOMの内部要素ではなく、ホスト要素から発行されるようにリダイレクトされます.(.getDestinationInsertionPoints()は、調整されたイベントパスを表示します.)
    次のイベントはshadowの境界を越えられません.
  • abort
  • error
  • select
  • change
  • load
  • reset
  • resize
  • scroll
  • selectstart

  • カスタム要素
    シーンの操作
  • 新しいHTML/DOM要素
  • を定義する
  • 他の要素に基づいて拡張要素
  • を作成する
  • ラベルにカスタム機能のセットをバインドする
  • 既存のDOM要素を拡張するAPI
  • 新しい要素の登録event.pathはカスタム要素を作成できます
  • の最初のパラメータは、要素のラベル名です.このラベル名にはハイフン(-)が含まれている必要があります.
  • の2番目のパラメータは、要素のprototypeを記述するための(オプション)オブジェクトです.ここでは、要素にカスタム機能(公開プロパティやメソッドなど)を追加できます.
  • var XFoo = document.registerElement('x-foo', {
      prototype: Object.create(HTMLElement.prototype)
    });
    //         ,              
    var myapp = {}; 
    myapp.XFoo = document.registerElement('x-foo');
    //                 B     A,   A        B   prototype。
    var MegaButton = document.registerElement('mega-button', {
      prototype: Object.create(HTMLButtonElement.prototype)
    });
    //          
    var megaButton = document.createElement('button', 'mega-button');
    // 

    JS属性とメソッドの追加
    var XFooProto = Object.create(HTMLElement.prototype);
    
    // 1.   x-foo    foo()   
    XFooProto.foo = function() {
      alert('foo() called');
    };
    
    // 2.        “bar”  
    Object.defineProperty(XFooProto, "bar", {value: 5});
    
    // 3.    x-foo    
    var XFoo = document.registerElement('x-foo', {prototype: XFooProto});
    
    // 4.      x-foo   
    var xfoo = document.createElement('x-foo');
    
    // 5.     
    document.body.appendChild(xfoo);
    
    /*        */
    var XFoo = document.registerElement('x-foo', {
      prototype: Object.create(HTMLElement.prototype, {
        bar: {
          get: function() { return 5; }
        },
        foo: {
          value: function() {
            alert('foo() called');
          }
        }
      })
    });
    

    ライフサイクルコールバックメソッド
    コールバック名
    呼び出しポイント
    createdCallback
    要素インスタンスの作成
    attachedCallback
    ドキュメントへのインスタンスの挿入
    detachedCallback
    ドキュメントからインスタンスを削除
    attributeChangedCallback(attrName, oldVal, newVal)
    属性の追加、削除、または変更
    var proto = Object.create(HTMLElement.prototype);
    
    proto.createdCallback = function() {
      this.addEventListener('click', function(e) {
        alert('Thanks!');
      });
      this.innerHTML = "I'm an x-foo!";
    };
    proto.attachedCallback = function() {...};
    
    var XFoo = document.registerElement('x-foo', {prototype: proto});
    

    Shadow DOMで内部実装
  • 内部インプリメンテーションを隠す方法であって、ユーザを血まみれインプリメンテーションの詳細から隔離する.
  • 単純で効率的なスタイル分離.

  • Shadow DOMからの要素の作成は、レンダリングベースマーカーを作成する要素とよく似ています.createdCallback()コールバックとは異なります.
    var XFooProto = Object.create(HTMLElement.prototype);
    
    XFooProto.createdCallback = function() {
      // 1.         shadow root。
      var shadow = this.createShadowRoot();
    
      // 2.     。
      shadow.innerHTML = "I'm in the element's Shadow DOM!";
    };
    
    var XFoo = document.registerElement('x-foo-shadowdom', {prototype: XFooProto});
    

    テンプレートから要素を作成
    
    
    
    var proto = Object.create(HTMLElement.prototype, {
      createdCallback: {
        value: function() {
          var t = document.querySelector('#sdtemplate');
          var clone = document.importNode(t.content, true);
          this.createShadowRoot().appendChild(clone);
        }
      }
    });
    document.registerElement('x-foo-from-template', {prototype: proto});
    
    

    カスタム要素のスタイルを追加
    
    
    
      
  • Do
  • Re
  • Mi

  • Shadow DOMを使用する要素のスタイルを追加
  • Polymerドキュメント
  • Shadow DOM 201 - CSS and Styling

  • 使用:unresolved擬似クラススタイルコンテンツの点滅を回避(FOUC)
    使用:unresolved擬似クラススタイルコンテンツの点滅を回避(FOUC)
    登録後に表示されるラベル:
    
    
    document.registerElement()擬似クラスは、:unresolved要素にのみ使用でき、unresolvedから継承された要素には使用できません.
    
    
    
      I'm black because :unresolved doesn't apply to "panel".
      It's not a valid custom element name.
    
    
    I'm red because I match x-panel:unresolved.
    

    履歴とブラウザのサポートHTMLUnkownElementが存在するかどうかを確認します.
    function supportsCustomElements() {
      return 'registerElement' in document;
    }
    
    if (supportsCustomElements()) {
      // Good to go!
    } else {
      // Use other libraries to create components.
    }
    

    リファレンス
  • Shadow DOM 101
  • Shadow DOM 201 - CSS and Styling
  • Shadow DOM 301 - CSS and Styling
  • Custom Elements
  • Polymer