首页 > web前端 > css教程 > HTML Web组件使渐进式增强和CSS封装更加容易!

HTML Web组件使渐进式增强和CSS封装更加容易!

Jennifer Aniston
发布: 2025-03-08 09:44:12
原创
929 人浏览过

HTML Web Components Make Progressive Enhancement and CSS Encapsulation Easier!

杰里米·基思(Jeremy Keith)去年的洞察力文章向我介绍了HTML Web组件,这一启示改变了我的Web开发方法。 他的关键点引起了人们的共鸣:虽然您可以通过DOM操纵和事件处理实现相同的结果,但Web组件提供了更强大,可移植和可维护的解决方案,但遵守单个责任原则。 >我最初的误解是所有Web组件仅依赖于JavaScript和Shadow dom。 虽然这是可能的,但一种卓越的方法,尤其是对于渐进式增强倡导者,利用了Web组件的固有HTML功能。 从根本上讲,它们是HTML。 安迪·贝尔(Andy Bell)最近的工作提供了有关渐进式增强的进一步背景(尽管本文范围之内)。 >让我们探索三个示例,展示了关键特征:CSS封装和进行性增强的可能性,而没有强制性的JavaScript依赖基本功能。 JavaScript将用于增强体验,但是即使没有它,核心功能仍然完整。 这些示例及其源代码可在我的Web UI样板组件库(Storybook)上找到。

>示例1:

>灵感来自克里斯·费迪南迪(Chris Ferdinandi)关于使用披露模式从头开始构建Web组件的教程的启发,此示例在其演示上扩展了。

核心是HTML。 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-expandedaria-controls)。这展示了进步的增强。 不需要其他CSS;造型是继承的。

>示例2:<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被封装:

无论JavaScript如何,都应用了
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简单:

&lt;webui-ajax-loader&gt;&lt;/webui-ajax-loader&gt;> javascript:

属性允许使用

pseudo-selector从组件外部进行SVG造型:
&lt;webui-ajax-loader&gt;&lt;/webui-ajax-loader&gt;
登录后复制
>

可以使用

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>
登录后复制
登录后复制
渐进增强是固有的;仅在支持JavaScript时才会出现加载程序。

>

结论

仅在需要时使用JavaScript来确定HTML的优先级

> HTML Web组件优先考虑HTML。 他们提供了一种强大的方法来构建强大,可维护和可访问的Web应用程序。

>

以上是HTML Web组件使渐进式增强和CSS封装更加容易!的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板