傑里米·基思(Jeremy Keith)去年的洞察力文章向我介紹了HTML Web組件,這一啟示改變了我的Web開發方法。 他的關鍵點引起了人們的共鳴:雖然您
>示例1:
>靈感來自克里斯·費迪南迪(Chris Ferdinandi)關於使用披露模式從頭開始構建Web組件的教程的啟發,此示例在其演示上擴展了。
<webui-disclosure></webui-disclosure>
包含一個按鈕,可以在<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的情況下,該按鈕(隱藏在hidden
屬性中)是無形的,並且顯示內容。 這表明了簡單的漸進式增強。 無論javaScript如何,都可以訪問內容。
>這通過通過ESC鍵添加閉合或單擊元素外(使用data-attribute
> s)來擴展Ferdinandi的演示。 定義自定義元素:
customElements.define('webui-disclosure', WebUIDisclosure);
>自定義元素名稱使用虛線(例如,<my-component></my-component>
)。 雖然破折號通常會分開單詞,但這並不是嚴格要求的。
使用TypeScript對預防錯誤是有益的,但是為簡單起見,JavaScript ES模塊結構是:
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()
>和connectedCallback()
處理(如Hawk Ticehurst所述)。 雖然對於基本功能不是必需的,但JavaScript增強了UX和可訪問性(添加aria-expanded
和aria-controls
)。這展示了進步的增強。 不需要其他CSS;造型是繼承的。
<webui-tabs></webui-tabs>
這個示例突出顯示了選項卡組件中的CSS封裝和漸進式增強。
html結構:
<webui-tabs> <div data-tablist=""> <a data-tab="" href="https://www.php.cn/link/7426f79c9a7f5af0a6cc457b2a7fb195">Tab 1</a> <a data-tab="" href="https://www.php.cn/link/60430f4a984aa0a534e027339a7580a7">Tab 2</a> <a data-tab="" href="https://www.php.cn/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>
CSS被封裝:
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]
)。 僅在啟用JavaScript時,才添加具有[data-tab]
屬性的樣式,從而提供漸進的增強功能。 樣式範圍範圍為role
,防止衝突。 簡單的後代選擇器可以替換複雜的方法。
可以通過JavaScript導入樣式表(僅當JavaScript可用時才消耗)
<webui-tabs></webui-tabs>
或者,可以使用Shadow dom:
>“ Light” DOM(組件標籤之間的內容)繼承了全局樣式。 陰影DOM需要內部樣式。戴夫·魯珀特(Dave Rupert)的文章闡明了外部樣式如何與影子dom相互作用。 JavaScript可以實現
>漸進式增強:import styles from './styles.css'; class WebUITabs extends HTMLElement { constructor() { super(); this.adoptedStyleSheets = [styles]; } } customElements.define('webui-tabs', WebUITabs);
JavaScript
添加了ARIA角色和鍵盤導航,從而增強了可訪問性。沒有JavaScript,默認行為(鏈接到面板)仍然可以訪問。class WebUITabs extends HTMLElement { connectedCallback() { this.attachShadow({ mode: 'open' }); this.shadowRoot.innerHTML = ` <!-- styles go here --> `; } } customElements.define('webui-tabs', WebUITabs);
>示例3:
這個示例完全由JavaScript使用Shadow dom生成,僅在啟用JavaScript時才會渲染。 它用於指示AJAX請求的加載狀態。
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);
html簡單:
<webui-ajax-loader></webui-ajax-loader>
> javascript:
屬性允許使用
pseudo-selector從組件外部進行SVG造型:<webui-ajax-loader></webui-ajax-loader>
可以使用
css自定義屬性:class WebUIAjaxLoader extends HTMLElement { constructor() { super(); const shadow = this.attachShadow({ mode: 'open' }); shadow.innerHTML = ` <svg part="svg" role="img"><title>loading</title> <circle cx="50" cy="50" r="47"></circle></svg> `; } } customElements.define('webui-ajax-loader', WebUIAjaxLoader);
<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>
>
結論>
以上是HTML Web組件使漸進式增強和CSS封裝更加容易!的詳細內容。更多資訊請關注PHP中文網其他相關文章!