杰里米·基思(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中文网其他相关文章!