ジェレミー・キースの洞察に満ちた記事は、昨年、HTML Webコンポーネントを紹介しました。これは、Web開発へのアプローチを変えた啓示です。 彼の重要なポイントは深く共鳴しました:は
がDOMの操作とイベント処理で同じ結果を達成することができましたが、Webコンポーネントは、より堅牢でポータブルで保守可能なソリューションを提供し、単一の責任の原則に準拠しています。
私の最初の誤解は、すべてのWebコンポーネントがJavaScriptとShadow Domにのみ依存しているということでした。 これは可能ですが、特にプログレッシブエンハンスメントの支持者にとって優れたアプローチは、Webコンポーネントの固有のHTML機能を活用しています。 基本的には、htmlです。 Andy Bellの最近の研究は、プログレッシブエンハンスメントに関するさらなるコンテキストを提供します(ただし、この記事の範囲外)。重要な機能を紹介する3つの例を調べてみましょう:基本的な機能に必須のJavaScript依存性なしに、CSSカプセル化と進行性強化の可能性。 JavaScriptはエクスペリエンスを向上させるために使用されますが、コア機能はなくてもそのままです。 これらの例は、ソースコードとともに、GitHubのWeb UI VoilerPlateコンポーネントライブラリ(ストーリーブック)で入手できます。
例1:<webui-disclosure></webui-disclosure>
コアはHTMLです。 Webコンポーネントは、カスタム要素名を許可します。ここでは、
。<webui-disclosure data-bind-click-outside="" data-bind-escape-key=""> Show / Hide <div data-content=""> <p>Content to be shown/hidden.</p> </div> </webui-disclosure>
属性を介して非表示)が見えなくなり、コンテンツが表示されます。 これは、単純な進行性の強化を示しています。 コンテンツは、JavaScriptに関係なくアクセスできます
これにより、ESCキーまたは要素の外側のクリックを介して閉鎖を追加することにより、Ferdinandiのデモが拡張されます(hidden
sを使用)。 カスタム要素は定義されています:
data-attribute
カスタム要素名は、Dashed-Identを使用します(例:
customElements.define('webui-disclosure', WebUIDisclosure);
タイプスクリプトの使用はエラー予防に有益ですが、簡単にするために、JavaScript ESモジュール構造は次のとおりです。
<my-component></my-component>
および
で処理されます(Hawk Ticehurstによって説明されています)。 基本的な機能には不可欠ではありませんが、JavaScriptはUXとアクセシビリティを強化します(class WebUIDisclosure extends HTMLElement { constructor() { super(); this.trigger = this.querySelector('[data-trigger]'); this.content = this.querySelector('[data-content]'); this.bindEscapeKey = this.hasAttribute('data-bind-escape-key'); this.bindClickOutside = this.hasAttribute('data-bind-click-outside'); if (!this.trigger || !this.content) return; this.setupA11y(); this.trigger?.addEventListener('click', this); } setupA11y() { // Add ARIA props/state to button. } handleEvent(e) { // 1. Toggle visibility of content. // 2. Toggle ARIA expanded state on button. } connectedCallback() { document.addEventListener('keyup', (e) => { // Handle ESC key. }); document.addEventListener('click', (e) => { // Handle clicking outside. }); } disconnectedCallback() { // Remove event listeners. } }
constructor()
例2:connectedCallback()
aria-expanded
aria-controls
この例は、CSSのカプセル化とタブ付きコンポーネントの進行性の強化を強調しています。
<webui-tabs></webui-tabs>
デフォルトスタイル(
、<webui-tabs> <div data-tablist=""> <a data-tab="" href="//m.sbmmt.com/link/7426f79c9a7f5af0a6cc457b2a7fb195">Tab 1</a> <a data-tab="" href="//m.sbmmt.com/link/60430f4a984aa0a534e027339a7580a7">Tab 2</a> <a data-tab="" href="//m.sbmmt.com/link/9d4f684ba088d28ad1c2ae7d0aee496a">Tab 3</a> </div> <div data-tabpanel=""> <p>1 - Lorem ipsum dolor sit amet consectetur.</p> </div> <div data-tabpanel=""> <p>2 - Lorem ipsum dolor sit amet consectetur.</p> </div> <div data-tabpanel=""> <p>3 - Lorem ipsum dolor sit amet consectetur.</p> </div> </webui-tabs>
属性を持つスタイルは、JavaScriptが有効になっている場合にのみ追加され、進行性の強化を提供します。 スタイルは
にスコープされ、競合を防ぎます。 単純な子孫セレクターは、BEMのような複雑な方法論を置き換えることができますwebui-tabs { [data-tablist] { /* Default styles without JavaScript */ } [data-tab] { /* Default styles without JavaScript */ } [role='tablist'] { /* Style role added by JavaScript */ } [role='tab'] { /* Style role added by JavaScript */ } [role='tabpanel'] { /* Style role added by JavaScript */ } }
[data-tablist]
代わりに、インラインスタイルをShadow dom:[data-tab]
を使用して注入することができます
role
<webui-tabs></webui-tabs>
「ライト」dom(コンポーネントタグ間のコンテンツ)は、グローバルスタイルを継承します。 Shadow Domには内部スタイルが必要です。 Dave Rupertの記事は、外部スタイルがShadow Domとどのように相互作用するかを明確にしています。
を使用して進行性の強化が達成されます
import styles from './styles.css'; class WebUITabs extends HTMLElement { constructor() { super(); this.adoptedStyleSheets = [styles]; } } customElements.define('webui-tabs', WebUITabs);
例3:
class WebUITabs extends HTMLElement { connectedCallback() { this.attachShadow({ mode: 'open' }); this.shadowRoot.innerHTML = ` <!-- styles go here --> `; } } customElements.define('webui-tabs', WebUITabs);
htmlは単純です:
javascript:
class WebUITabs extends HTMLElement { constructor() { super(); // ... (querySelector, etc.) ... this.createTabs(); this.tabTriggers.forEach((tabTrigger, index) => { tabTrigger.addEventListener('click', (e) => { this.bindClickEvent(e); }); tabTrigger.addEventListener('keydown', (e) => { this.bindKeyboardEvent(e, index); }); }); } createTabs() { // 1. Hide all tabpanels initially. // 2. Add ARIA props/state to tabs & tabpanels. } bindClickEvent(e) { e.preventDefault(); // Show clicked tab and update ARIA props/state. } bindKeyboardEvent(e, index) { e.preventDefault(); // Handle keyboard ARROW/HOME/END keys. } } customElements.define('webui-tabs', WebUITabs);
<webui-ajax-loader></webui-ajax-loader>
pseudoセレクターを使用してコンポーネントの外側からSVGをスタイリングできます:CSSカスタムプロパティを使用できます:
<webui-disclosure data-bind-click-outside="" data-bind-escape-key=""> Show / Hide <div data-content=""> <p>Content to be shown/hidden.</p> </div> </webui-disclosure>
進行性の強化は固有です。ローダーは、JavaScriptがサポートされている場合にのみ表示されます
結論以上がHTML Webコンポーネントにより、プログレッシブエンハンスメントとCSSカプセル化が容易になります!の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。