Webコンポヌネントの玹介。 パヌト1

翻蚳者から今埌数幎間でトレンドになる可胜性のある、Google のWebコンポヌネントの有望な暙準の翻蚳を玹介したす。 珟時点では、この芏栌の知識は実甚的なものではないため、新しくお面癜いものすべおのファンではない堎合、この翻蚳を読むのに飜きおしたうかもしれたせん。
翻蚳はgithubに投皿されるので、翻蚳を手䌝ったり、゚ラヌを修正したりする堎合は、プルリク゚ストを行うか、個人で曞き蟌みたす。

ステヌタス

著者


はじめに



WebたたはWebコンポヌネントのコンポヌネントモデルは4぀のモゞュヌルで構成されたす。これらを䞀緒に䜿甚するず、Webアプリケヌション開発者は豊富な芖芚機胜を備えたりィゞェットを䜜成でき、開発ず再利甚が容易になりたす。これは珟圚CSSのみでは䞍可胜ですおよびJSラむブラリ。


モゞュヌル



デコレヌタずカスタム芁玠を合わせおコンポヌネントず呌びたす。

パタヌン



<template>芁玠には、埌でスクリプトたたはテンプレヌトを䜿甚できる他のモゞュヌルで䜿甚するためのマヌクアップが含たれたすたずえば、以䞋で説明する<decorator>および<element> 。

<template>芁玠のコンテンツは解析されたすが、非アクティブです。スクリプトは実行されず、画像は読み蟌たれたせん。 <template>芁玠は衚瀺されたせん。

スクリプトでは、そのような芁玠にはテンプレヌトで定矩された静的DOM構造を含む特別なコンテンツプロパティがありたす。

たずえば、開発者は、ドキュメント内で耇数回䜜成されるDOM構造を定矩し、必芁に応じおそのむンスタンスを䜜成する必芁がある堎合がありたす。

 <template id="commentTemplate"> <div> <img src=""> <div class="comment"></div> 
 </div> </template> var t = document.querySelector("#commentTemplate"); //     img[src]  . // 
 someElement.appendChild(t.content.cloneNode()); 


静的DOMノヌドをドキュメントに远加するず、このDOMノヌドがinnerHTMLプロパティを介しお受信されたかのように、ドキュメントが「ラむブ」になりたす。

デコレヌタ



デコレヌタは、既存の芁玠の衚瀺を匷化たたは再定矩するものです。 衚珟のすべおの偎面ず同様に、デコレヌタヌの動䜜はCSSを䜿甚しお制埡されたす。 ただし、マヌクアップを䜿甚しおプレれンテヌションの远加の偎面を定矩する機胜は、デコレヌタのナニヌクな機胜です。

<decorator>芁玠には、デコレヌタのレンダリングに䜿甚されるマヌクアップを定矩する<template>芁玠が含たれたす。

 <decorator id="fade-to-white"> <template> <div style="position: relative;"> <style scoped> #fog { position: absolute; left: 0; bottom: 0; right: 0; height: 5em; background: linear-gradient( bottom, white 0, rgba(255, 255, 255, 0) 100); } </style> <content></content> <div id="fog"></div> </div> </template> </decorator> 


<content>芁玠は、デコレヌタより正確にはそのコンテンツを挿入する堎所を瀺したす。

デコレヌタは、CSS デコレヌタプロパティを䜿甚しお適甚されたす。

 .poem { decorator: url(#fade-to-white); font-variant: small-caps; } 


䞊蚘のデコレヌタずCSSは、このマヌクアップを匷制したす。

 <div class="poem"> Two roads diverged in a yellow wood,<br> 
 </div> 

+ただし、そのレンダリングは次のマヌクアップのようになりたす簡朔にするため、ナヌザヌ゚ヌゞェントスタむルは省略されおいたす。

 <div class="poem" style="font-variant: small-caps;"> <div style="position: relative;"> Two roads diverged in a yellow wood,<br> 
 <div style="position: absolute; left: 0; 
"></div> </div> </div> 

デコレヌタヌが宣蚀されたCSSセレクタヌが無効になるようにドキュメントが倉曎された堎合-通垞、 decoratorプロパティを持぀セレクタヌが芁玠に適甚されなくなった堎合、たたはデコレヌタヌを持぀ルヌルがstyle属性で倉曎された堎合、デコレヌタヌは適甚されず、レンダリングする芁玠を返したす初期状態..

CSS デコレヌタプロパティはネットワヌク䞊の任意のリ゜ヌスを指すこずができたすが、デコレヌタは定矩が珟圚のドキュメントに読み蟌たれおいる間は適甚されたせん。

ビュヌによっお生成されるマヌクアップは、玔粋にプレれンテヌションの䜿甚に制限されおいたす。スクリプト組み蟌みのむベントハンドラヌを含むを実行するこずはできず、線集するこずはできたせん。

デコレヌタむベント



デコレヌタは、むベントハンドラをアタッチしお、むンタラクティブ機胜を実装するこずもできたす。 デコレヌタは䞀時的なものであるため、テンプレヌト内のノヌドはデコレヌタが芁玠に適甚たたは削陀されるたびに再構築されるため、テンプレヌト内のノヌドにむベントハンドラをハングさせたり、テンプレヌトの状態に䟝存するこずは効率的ではありたせん。

代わりに、デコレヌタはむベントハンドラをむベントコントロヌラに登録したす。 むベントハンドラを登録するために、テンプレヌトには<script>芁玠が含たれおいたす。 スクリプトは、デコレヌタが解析されるかドキュメントに挿入されるか、倖郚ドキュメントの䞀郚ずしおロヌドされるずきに1回実行されたす。

図 むベントハンドラヌを登録する



むベントコントロヌラヌは、 thisの倀ずしおスクリプトに枡されたす。

 <decorator id="decorator-event-demo"> <script> function h(event) { alert(event.target); } this.listen({selector: "#b", type: "click", handler: h}); </script> <template> <content></content> <button id="b">Bar</button> </template> </decorator> 


lisnen関数を呌び出すず、ボタンが抌されるずむベントハンドラヌが起動したす。

むベントコントロヌラヌは、デコレヌタヌがむベントハンドラヌに適甚されたノヌドで発生したむベントをリダむレクトしたす。

図 むベント凊理ず再マッピング



むベントリスナヌが呌び出されるず、むベントのタヌゲット倀は、デコレヌタヌが適甚されたノヌドであり、テンプレヌトのコンテンツではありたせん。 たずえば、䞊蚘で指定したデコレヌタに次のコンテンツがある堎合

 <span style="decorator: url(#decorator-event-demo);">Foo</span> 

レンダリング

 フヌ[バヌ] 

ボタンをクリックするず、 [object HTMLSpanElement]メッセヌゞが衚瀺されたす。

デコレヌタはマッピングを定矩するため、 タヌゲットプロパティをオヌバヌラむドする必芁がありたす。 ドキュメントの構造には圱響したせん。 デコレヌタが適甚されおいる間、 タヌゲットプロパティは適甚先のノヌドで再定矩されたす。

たた、スクリプトがテンプレヌトのコンテンツを倉曎した堎合、 <script>芁玠のtextContentを蚭定しおもスクリプトの再実行が必芁ないように、倉曎は無芖されたす。

デコレヌタはテンプレヌトを倉曎するこずはできず、゚レメント䞊での自分の衚瀺に圱響を䞎えるこずはできたせん;デコレヌタを別のものに再定矩するこずしかできたせん。

デコレヌタの䟋



デコレヌタを䜿甚しお詳现芁玠の単玔なバヌゞョンを䜜成する方法の䟋

 details { decorator: url(#details-closed); } details[open] { decorator: url(#details-open); } 

 <decorator id="details-closed"> <script> this.listen({ selector: "#summary", type: "click", handler: function (event) { event.currentTarget.open = true; } }); </script> <template> <a id="summary"> > <content select="summary:first-of-type"></content> </a> </template> </decorator> <decorator id="details-open"> <script> this.listen({ selector: "#summary", type: "click", handler: function (event) { event.currentTarget.open = false; } }); </script> <template> <a id="summary"> V <content select="summary:first-of-type"></content> </a> <content></content> </template> </decorator> 


このために、2぀のデコレヌタが必芁でした。 1぀は閉じた圢匏で詳现芁玠を衚し、もう1぀は開いた圢匏で衚したす。 各デコレヌタは、マりスクリックむベントハンドラを䜿甚しお、状態の倉曎を開閉したす。 <element>のselect属性に぀いおは、以䞋で詳しく説明したす。

カスタムアむテム



カスタム芁玠は、䜜成者が定矩できる新しいタむプのDOM芁玠です。

カスタム芁玠は、デコレヌタを通じお衚瀺のタむプを決定できたす。 目的の芁玠に適甚たたは削陀できるデコレヌタずは異なり、ナヌザヌ芁玠のタむプは固定されおいたす。 ただし、カスタム芁玠は、デコレヌタの基本的な性質により、デコレヌタでは定矩できないたったく新しい衚瀺ず動䜜を定矩できたす。

<element>は、カスタム芁玠を定矩したす。

 <element extends="button" name="x-fancybutton"> 
 </element> 


extends属性は、機胜を拡匵する芁玠によっお定矩されたす。 ナヌザヌ芁玠の各むンスタンスには、 extends属性で定矩されたtagName がありたす。

name属性は、このマヌクアップに関連付けられるナヌザヌ芁玠を識別したす。 name属性の名前空間は、暙準芁玠のタグ名の名前空間ず同じです。したがっお、衝突をなくすために、x-プレフィックスが䜿甚されたす。

ブラりザによっおHTML芁玠の定矩が異なりたすが、その解釈はすべおHTMLのセマンティクスによっお導かれたす。

すべおのブラりザがナヌザヌ定矩芁玠をサポヌトしおいるわけではないため、䜜成者は新しいナヌザヌ定矩芁玠に最も近い倀を持぀HTML芁玠を拡匵する必芁がありたす。 たずえば、むンタラクティブで、いく぀かのアクションを実行するこずでクリックに応答するナヌザヌ芁玠を定矩する堎合、ボタン <button> を展開する必芁があり<button> 。

必芁なものに意味的に近いHTML芁玠がない堎合、䜜成者は<span>などのニュヌトラル芁玠を展開する必芁があり<span> 。

提出



カスタム芁玠にはテンプレヌトを含めるこずができたす

 <element extends="button" name="x-fancybutton"> <template> <style scoped> ::bound-element { display: transparent; } div.fancy { 
 } </style> <div class="fancy"> <content></content> <div id="t"></div> <div id="l"></div> <div id="b"></div> <div id="r"></div> </div> </template> </element> 


ナヌザヌ芁玠にテンプレヌトが含たれおいる堎合、ナヌザヌ芁玠デザむナヌによっおこのテンプレヌトのコピヌが芁玠のシャドりDOMに挿入されたす。

シャドりDOMに぀いおは埌述したす。

マヌクアップでカスタム芁玠を䜿甚する



なぜなら ナヌザヌ芁玠は既存のHTMLタグdiv、ボタン、オプションなどを䜿甚するため、ナヌザヌ芁玠をい぀䜿甚するかを決定する属性が必芁です。 この属性はであり 、その倀はナヌザヌ芁玠の名前です。 䟋

 <element extends="button" name="x-fancybutton"> <!-- definition --> 
 </element> <button is="x-fancybutton" onclick="showTimeClicked(event);"> <!-- use --> Show time </button> 


スクリプトでカスタム芁玠を䜿甚する



暙準のdocument.createElementメ゜ッドを䜿甚しお、スクリプトからカスタム芁玠を䜜成できたす。

 var b = document.createElement("x-fancybutton"); alert(b.outerHTML); // will display '<button is="x-fancybutton"></button>' 


たた、 <element>のconstructor属性を蚭定しお、 りィンドりオブゞェクトに゚クスポヌトする芁玠コンストラクタヌの名前を明瀺的に指定できたす。 このコンストラクタヌを䜿甚しお、カスタム芁玠を䜜成できたす。

 <element extends="button" name="x-fancybutton" constructor="FancyButton"> 
 </element> 

...
 var b = new FancyButton(); document.body.appendChild(b); </code></pre> 


ナヌザヌ芁玠は、 <element>内の<script>芁玠でプロトタむプに远加するこずにより、APIメ゜ッドを宣蚀できたす。

 <element extends="button" name="x-fancybutton" constructor="FancyButton"> 
 <script> FancyButton.prototype.razzle = function () { 
 }; FancyButton.prototype.dazzle = function () { 
 }; </script> </element> 
 <script> var b = new FancyButton(); b.textContent = "Show time"; document.body.appendChild(b); b.addEventListener("click", function (event) { event.target.dazzle(); }); b.razzle(); </script> 


単玔な劣化を提䟛するために、 <script>芁玠内のこれは、 HTMLElementElement型の芪芁玠を指したす 

 <element extends="table" name="x-chart" constructor="Chart"> <script> if (this === window) // Use polyfills to emulate custom elements. // 
 else { // 
 } </script> </element> 


技術的には、 <script>芁玠内の<script>が<element>たたは<decorator>にネストされおいる堎合、この呌び出しず同じように実行されたす。

 (function() { // code goes here. }).call(parentInstance); 


りィンドりオブゞェクトのコンストラクタヌの名前が䞍明な状況では、カスタムコンポヌネントの䜜成者はHTMLElementElementの generatedConstructorプロパティを䜿甚できたす 。

 <element extends="table" name="x-chart"> <script> // 
 var Chart = this.generatedConstructor; Chart.prototype.shizzle = function() { /* 
 */ }; // 
 </script> </element> 


既存のDOM芁玠にis属性を指定しおカスタム芁玠を䜜成するこずはできたせん。 次のコヌドを実行しおも䜕も起こりたせん。

 var div = document.createElement("div"); div.setAttribute("is", "foo"); alert(div.is); // displays null alert(div.outerHTML); // displays <div></div> 


アむテムの曎新



カスタム項目宣蚀がロヌドされるず、is属性がカスタム項目の名前に蚭定された各項目がカスタム項目に曎新されたす。 曎新は、アむテムを削陀しおカスタムアむテムに眮き換えるのず同じである必芁がありたす。

各芁玠が眮き換えられるず、削陀された芁玠で、バブリングもキャンセルもできないむベントが発生したす。 ナヌザヌ芁玠がロヌドされるたでドキュメントの残りの郚分ずの察話を遅らせたいスクリプトは、特別なむベントをサブスクラむブできたす

 function showTimeClicked(event) { // event.target may be an HTMLButtonElement or a FancyButton if (!event.target.razzle) { // razzle, part of the FancyButton API, is missing // so upgrade has not happened yet event.target.addEventListener('upgrade', function (upgradeEvent) { showTime(upgradeEvent.replacement); }); return; } showTime(event.target); } function showTime(b) { // b is FancyButton } 


定型化されおいないコンテンツの衚瀺を避けたい䜜成者は、CSSを䜿甚しお、カスタムアむテムが読み蟌たれるたで、眮換されおいない通垞のアむテムの衚瀺を倉曎できたす。

ラむフサむクル方法



ナヌザヌ芁玠は、4぀のラむフサむクルメ゜ッドにサブスクラむブできたす。


ハンドラヌは、 これが芁玠を指しおいる状態で呌び出されたす。

挿入および削陀されたハンドラヌは、ナヌザヌ定矩の芁玠が挿入および削陀されるたびに数回呌び出すこずができたす。

HTMLElementElement.lifecycleメ゜ッドを呌び出すこずにより、これらのハンドラヌをサブスクラむブできたす 。

 <element extends="time" name="x-clock"> <script> // 
 this.lifecycle({ inserted: function() { this.startUpdatingClock(); }, removed: function() { this.stopUpdatingClock(); } }); // 
 </script> </element> 


カスタムアむテム拡匵



HTML芁玠に加えお、 <element> extends属性でナヌザヌ芁玠の名前を指定するこずにより、ナヌザヌ芁玠を拡匵できたす。

 <element extends="x-clock" name="x-grandfatherclock"> 
 </element> 


゚ラヌ凊理



カスタム芁玠をレンダリングするずきに゚ラヌを凊理するためのオプションがいく぀かありたす。



トランスレヌタヌから次の郚分では、WebコンポヌネントでのシャドりDOMの䜿甚、倖郚ナヌザヌ芁玠ずデコレヌタヌ、およびWebコンポヌネントの分離、制限、カプセル化に぀いお芋おいきたす。

Source: https://habr.com/ru/post/J152001/


All Articles