在设计我的数字花园时,我知道我想要一个可爱的黑暗模式切换开关。绘制完 SVG 后,我开始构建一个 Web 组件,该组件具有与 React 中的暗模式切换功能相同的功能。这包括我在可访问性审核我的网站时学到的所有内容。
除了更改主题之外,切换还需要考虑用户的首选颜色方案选择,并在重新加载时保留用户的偏好。为了实现可访问性,切换的屏幕阅读器公告必须有意义(例如“深色模式切换打开”)。由于我想显示 SVG 而不是带有文本的复选框,因此我必须添加焦点和悬停样式以及悬停时显示的标签。
首先,我需要一个用于创建 HTML 元素的 Toggle 类。使用自定义元素 API,我将定义
使用类的构造函数,我设置了
HTML 就位后,我向该类添加一个connectedCallback 函数。自定义元素 API 的这一部分定义了在组件内使用的函数,并在组件插入 DOM 时执行代码。
// /components/toggle.js class Toggle extends HTMLElement { constructor() { super(); this.innerHTML = ` <label title="dark mode toggle"> <input type="checkbox" id="theme-toggle" class="theme-switch" /> <svg id="daisy">{SVG code removed for brevity}</svg> </label> ` this.setAttribute("class", "toggle-component"); } connectedCallback() { function switchTheme(e) { if (e.target.checked) { setTheme('dark'); return; } setTheme('light'); }; function setTheme(themeName) { localStorage.setItem('theme', themeName); document.documentElement.setAttribute('data-theme', themeName); }; function setCheckBox(toggleSwitch, theme) { toggleSwitch.checked = theme === 'dark' ? true : false; } function keepTheme() { const toggleSwitch = document.querySelector('#theme-toggle'); toggleSwitch.addEventListener('change', switchTheme, false); const theme = localStorage.getItem('theme'); if (theme) { setTheme(theme); setCheckBox(toggleSwitch, theme); return; }; const prefersLightTheme = window.matchMedia('(prefers-color-scheme: light)'); if (prefersLightTheme.matches) { setTheme('light'); return; }; setTheme('dark'); setCheckBox(toggleSwitch, 'dark'); }; document.addEventListener("DOMContentLoaded", keepTheme); } } customElements.define("toggle-component", Toggle);
因为
keepTheme 的其余部分致力于在加载时选择正确的主题。首先,它检查 localStorage 以查看用户的首选项是否已设置。接下来,它检查prefers-color-scheme是否设置为“light”。最后,它默认为深色模式。对于深色和浅色模式,我调用 setTheme。对于深色模式,我也调用setCheckbox。该复选框以未选中状态安装。屏幕阅读器将宣布“深色模式”以及是否选中该复选框。要获得诸如“选中深色模式切换”或“打开深色模式切换”之类的公告,当我在加载时将主题设置为“深色”时,我必须以编程方式选中该复选框。
我选择绘制一个相当简单的设计,这样我就可以将 SVG 代码直接放入 Web 组件中,并以编程方式更改填充颜色。这样,雏菊的背景颜色始终与主题相匹配。接下来,我使用不透明度:0;隐藏复选框并将其放置在图像的中间。最后,我添加了悬停和焦点样式。
// /components/toggle.js class Toggle extends HTMLElement { constructor() { super(); this.innerHTML = ` <label title="dark mode toggle"> <input type="checkbox" id="theme-toggle" class="theme-switch" /> <svg id="daisy">{SVG code removed for brevity}</svg> </label> ` this.setAttribute("class", "toggle-component"); } connectedCallback() { function switchTheme(e) { if (e.target.checked) { setTheme('dark'); return; } setTheme('light'); }; function setTheme(themeName) { localStorage.setItem('theme', themeName); document.documentElement.setAttribute('data-theme', themeName); }; function setCheckBox(toggleSwitch, theme) { toggleSwitch.checked = theme === 'dark' ? true : false; } function keepTheme() { const toggleSwitch = document.querySelector('#theme-toggle'); toggleSwitch.addEventListener('change', switchTheme, false); const theme = localStorage.getItem('theme'); if (theme) { setTheme(theme); setCheckBox(toggleSwitch, theme); return; }; const prefersLightTheme = window.matchMedia('(prefers-color-scheme: light)'); if (prefersLightTheme.matches) { setTheme('light'); return; }; setTheme('dark'); setCheckBox(toggleSwitch, 'dark'); }; document.addEventListener("DOMContentLoaded", keepTheme); } } customElements.define("toggle-component", Toggle);
我需要做的就是在
中导入我的样式表和组件脚本。 HTML 页面的。然后我可以调用/* /styles/styles.css */ [data-theme="light"] { --toggle-background: #242D54; } [data-theme="dark"] { --toggle-background: #282e53; } #daisy path { fill: var(--toggle-background); } .theme-switch { position: relative; bottom: 30px; left: 55px; width: 1em; height: 1em; opacity: 0; } .theme-switch:focus + #daisy path, .theme-switch:hover + #daisy path { fill: white; } .theme-switch:focus + #daisy { outline: 3px solid white; outline-offset: 5px; }
我很高兴让我的黑暗模式切换在 Web 组件中像在 React 中一样工作。您可以在我的数字花园中实时查看此内容,并在 GitHub 存储库中查看完整代码。
以上是HTML Web 组件中的深色模式切换的详细内容。更多信息请关注PHP中文网其他相关文章!