Webコンポーネントの構築


2015年に戻って、私は私の最初のフロントエンドのフレームワーク- angularjsを学んでの最中だった.私がそれを思ったのは、カスタム機能を持つHTMLタグを構築しているということでした.もちろん、それは本当に起こっていたものではなかったが、それは学習曲線を下げるのを助けました.
さて、実際にWebコンポーネントを使用して独自のHTMLタグを構築することができます!彼らはまだ実験的な機能です-彼らはクロムとオペラで動作し、Firefoxで有効にすることができますが、まだサファリとエッジで実装されていません.一度、彼らは完全にロールバックすると、彼らは純粋なバニラJavaScriptで再利用可能なコンポーネントを構築するためのさらに素晴らしいツールになる-ライブラリやフレームワークが必要!

学習過程
私はバニラJSで書かれたWebコンポーネントの記事や例を見つけるのに苦労しました.Webコンポーネントをサポートしていないブラウザ用のポリフィルを含むWebコンポーネントを書くためのフレームワークです.フレームワークはものすごい音です、そして、私は将来それで働くことを試みるかもしれません、しかし、私はちょうどこの特定のプロジェクトのためにちょうどバニラJavascriptを使いたかったです.
私は大部分はMDN プロジェクトをビルドするためにシャドウDOMに関するドキュメント.私もcodepenとWebComponentサイトを見ました、しかし、私は私が構築したかったものに似ていたどちらかにあまりにも多くを見つけませんでした.
私も本当に好き!それはWebコンポーネントを使用する利点のいくつかをカバーしています:彼らはすべてのフレームワークで動作し、彼らは単にバニラJavaScriptを使用しているので実装し、理解するのは簡単です.

ファイナルプロジェクト
私のプロジェクトの多くでは、私は両方の個人的なブランディングのための同様のデザインスキームを使用して、私は新しいデザインを思い付く必要はありません!特に、それぞれの文字が異なる色で、その上に落ちているアニメーションがある見出しを使用します.個人サイトalispit.tel これはかなり良い例です!私はまた、私の履歴書、会議のスライドにそのテキストを持って、私は近い将来、他のサイトのためにそれを使用する計画を持っている!CSSは個々の文字を対象とすることができません.したがって、それぞれの文字をspan . これはかなりの痛みを書くことができますので、私はこれはWebコンポーネントを使用するのに最適な場所だった!

Webコンポーネントを書いている人に記事を見つけるのが難しかったので、ここでコードとともに徹底的に行くつもりです.
まず、WebコンポーネントをレンダリングするHTMLコードは次のようになります.
  <rainbow-text text="hello world" font-size="100"></rainbow-text>
Webコンポーネントをコールするrainbow-text そして、それは2つの属性を持っています:テキストは、コンポーネントがレンダリングされるもの、およびフォントサイズです.また、使用することができますslots and templates コンテンツを挿入するしかし、私のユースケースでは、追加のオーバーヘッドを追加しました.私はテキストを入力して、文字で区切られたテキストで一連のHTML要素を出力したかったので、最も簡単な方法は特にシャドウDOMで属性によってテキストを通過することでした.
それで、影DOMは何ですか?それは実際に新しいではない、それはWebコンポーネントに固有ではありません.シャドウDOMはDOM要素のサブツリーをそれ自身のスコープで導入する.また、子要素を隠すことができます.例えば、video 要素は実際にHTML要素のコレクションですしかし、我々が1をつくって、それを調べるとき、我々はvideo タグ!シャドウドームのクールな部分は、私にとっては、スタイリングがスコープされていた!私が私のドキュメントにスタイルを加えるならばdiv s、スタイルは影DOMの中のどんな要素にも影響しません.逆に、影DOMの中のスタイルは、外部文書のDOMの要素に影響を与えません.これはVueの私のお気に入りの機能の一つであるので、私はフレームワークなしで似たようなものを実装することができたことを非常に興奮していた!
カスタム要素を実装するJavaScriptコードに移動しましょう.まず、組み込みのJavaScriptクラスを作成しますHTMLElement クラス.私はES 6クラスを使いました、しかし、あなたが望むならば、あなたはJavaScriptのために古いOOP構文を使うこともできました.私は本当に、私は非常に反応からそれらに使用されているので、特にES 6のクラスを使用してお楽しみください!構文は身近でシンプルな感じ.
私が最初にしたことはconnectedCallback ライフサイクル法.これは、要素がレンダリングされたときに自動的に呼び出されますcomponentDidMount 反応して.また、あなたはconstructor 他のES 6クラスと同様ですしかし、私は何もデフォルト値または何も設定していなかったので、私は本当に1つの必要性を持っていませんでした.
インサイドconnectedCallback , まず、要素のシャドウDOMを呼び出しますthis.createShadowRoot() . さて、rainbow-text 要素はそれ自身の影DOMのルートです.したがって、子要素は隠されていて、スタイルと外部JavaScript突然変異のために彼ら自身の範囲を持ちます.次に、クラス内の属性を渡されるHTML属性から設定します.クラスの中でthis についてrainbow-text 要素.走る代わりにdocument.querySelector('rainbow-text').getAttribute('text') , 君は走るだけだthis.getAttribute('text') 得るtext 要素からの属性.
class RainbowText extends HTMLElement {
  connectedCallback () {
    this.createShadowRoot()
    this.text = this.getAttribute('text')
    this.size = this.getAttribute('font-size')
    this.render()
  }
render 私が書いたメソッドはconnectedCallback . また、disconnectedCallbackattributeChangedCallback LifeCycleメソッドは、あなたのコードに役立つ場合!私はちょうど私はかなり宗教的に従うサンディメッツのルールに付着するためにそれを分離!通常のバニラDOM操作とは異なるこのメソッドの1つのものは、私がshadowRoot の代わりにdocument または直接要素に!これはドキュメントのルートDOMの代わりにシャドウDOMに要素を添付します.
  render () {
    const div = document.createElement('div')
    div.classList.add('header')
    this.shadowRoot.appendChild(div)
    this.addSpans(div)
    this.addStyle()
  }
それから、各文字に対する個々のスパンをDOMに追加しました.これは基本的にバニラJavaScriptコードと同一です.
  addSpanEventListeners (span) {
    span.addEventListener('mouseover', () => { span.classList.add('hovered') })
    span.addEventListener('animationend', () => { span.classList.remove('hovered') })
  }

  createSpan (letter) {
    const span = document.createElement('span')
    span.classList.add('letter')
    span.innerHTML = letter
    this.addSpanEventListeners(span)
    return span
  }

  addSpans (div) {
    [...this.text].forEach(letter => {
      let span = this.createSpan(letter)
      div.appendChild(span)
    })
  }
最後に、スタイリングをシャドウDOMに追加しました.
  addStyle () {
    const styleTag = document.createElement('style')
    styleTag.textContent = getStyle(this.size)
    this.shadowRoot.appendChild(styleTag)
  }
このメソッドはstyle シャドウDOMにタグを付け、その中の要素を変更します.私は、CSSの全てを含むテンプレートリテラルに、ヘッダーのフォントサイズを接続するために、関数を使用しました.
コンポーネントを書くと、新しい要素を登録しなければなりませんでした.
try {
  customElements.define('rainbow-text', RainbowText)
} catch (err) {
  const h3 = document.createElement('h3')
  h3.innerHTML = "This site uses webcomponents which don't work in all browsers! Try this site in a browser that supports them!"
  document.body.appendChild(h3)
}
私も、非WebComponentフレンドリーなブラウザーのユーザーのために警告を加えました!
以下に、コンソールでの要素の表示方法を説明します.


次の手順
私はWebコンポーネントでの作業を楽しんだ!フレームワークなしで再利用可能なコンポーネントを作ることができるという考えはものすごいです.私がとても多色の名前を使うので、私が造ったものは本当に役に立ちます.私は、ちょうど以下を含みますscript その他私は私の個人的なサイトをコンポーネントを使用するように変換しません、しかし、私はそれがブラウザの向こう側に支持されることを望むので.また、状態やデータ管理のための明確なシステムは、Webコンポーネントの目標を与えられた意味をなす;しかし、他のフロントエンドフレームワークを必要とします.私は、これらの理由のためにフロントエンドフレームワークを使用し続けると思いますしかし、一度完全にサポートされている、彼らは素晴らしい使用されます!
Full Code
Example Use - ( WebComponentを使用しない)
私のパートOn Learning New Things シリーズ