为什么SVG不是“热”作为文本,在触发主题更改的单击操作时? (JavaScript/CSS/HTML)

发布于 2025-02-06 12:49:32 字数 3154 浏览 4 评论 0原文

为什么在此脚本中触发操作时,SVG不像文本那样“热”?

所有文本元素都很好地启动了正确的主题,但是当这些文本在完全相同的按钮ID位置替换为SVG时,代码不会选择相应的主题。

但是,它确实适用于SVG的周围区域,但不是SVG本身。

我希望能够同时使用 SVG本身 SVG稍加填充,以添加易用性。

<div id="scheme">
  <button id="auto">Auto</button>
  <button id="default">Default</button>
  <button id="light">Light</button>
  <button id="dark">Dark</button>
  <button id="blue">
    <svg width="20" height="20">
      <rect width="20" height="20" style="fill: lightgrey" />
      <!-- The face of this SVG does NOT actuate a theme change -->
    </svg>
  </button>
</div>

emo

https://jsfiddle.net/eu097xsd/eu097xsd/

'T在堆栈溢出的片段中工作,因此由于沙箱覆盖,因此必须将所有代码保存为完整页面,然后在现实世界中测试。

还请查看 https://github.com/beswork.com/besworks/theme-selector

/* Besworks Hot Theme Without Memory Problems
https://github.com/besworks/theme-selector */

let prefersDark = matchMedia('(prefers-color-scheme: dark)');
prefersDark.addEventListener('change', event => loadTheme());

function setTheme(theme) {
  if (theme == 'auto') {
    localStorage.removeItem('theme');
    loadTheme(null);
  } else {
    localStorage.setItem('theme', theme);
    applyTheme(theme);
  }
}

function loadTheme(theme) {
  theme = localStorage.getItem('theme');
  theme ??= (prefersDark.matches) ? 'dark' : 'default';
  applyTheme(theme);
}

function applyTheme(theme) {
  document.documentElement.className = theme;
}

window.setTheme = setTheme;

loadTheme();



let selector = document.getElementById('scheme');
  selector.addEventListener('click', event => {
    if (event.target == selector) { return; }
    window.setTheme(event.target.id);
});
:root.default { --bgr: #eee; --txt: #000; }
:root.light { --bgr: #ddc; --txt: #446; }
:root.dark { --bgr: #222; --txt: #a75; }
:root.blue { --bgr: #246; --txt: #eec; }
body { background: var(--bgr); color: var(--txt); margin: 1.5rem; }

#scheme button {
border: 1px solid red;
background: none;
color: inherit;
text-decoration: underline;
cursor: pointer;
}
    <h1> Select a theme to change the color scheme! </h1>
    <div id="scheme">
        <button id="auto">Auto</button>
        <button id="default">Default</button>
        <button id="light">Light</button>
        <button id="dark">Dark</button>
        <button id="blue">
        <svg width="20" height="20">
            <rect width="20" height="20" style="fill: lightgrey; stroke-width:1px; stroke: red;" />
        </svg>
        </button>
    </div>

Why does the SVG not as "hot" as the TEXT when triggering the action in this script?

All text elements fire the right theme nicely, BUT when these texts are replaced an SVG in the exact same button id location, the code does not select the corresponding theme.

It does however for the surrounding area of the SVG, but not the SVG itself.

I want to be able to use both the SVG itself and a little padding around the SVG for added ease of use.

<div id="scheme">
  <button id="auto">Auto</button>
  <button id="default">Default</button>
  <button id="light">Light</button>
  <button id="dark">Dark</button>
  <button id="blue">
    <svg width="20" height="20">
      <rect width="20" height="20" style="fill: lightgrey" />
      <!-- The face of this SVG does NOT actuate a theme change -->
    </svg>
  </button>
</div>

Demo

https://jsfiddle.net/eu097xsd/

localStorage doesn't work in snippets here on Stack Overflow due to sandboxing so all the code in the snippet must be saved as a full page then tested in a real-world environment.
Also check out https://github.com/besworks/theme-selector

/* Besworks Hot Theme Without Memory Problems
https://github.com/besworks/theme-selector */

let prefersDark = matchMedia('(prefers-color-scheme: dark)');
prefersDark.addEventListener('change', event => loadTheme());

function setTheme(theme) {
  if (theme == 'auto') {
    localStorage.removeItem('theme');
    loadTheme(null);
  } else {
    localStorage.setItem('theme', theme);
    applyTheme(theme);
  }
}

function loadTheme(theme) {
  theme = localStorage.getItem('theme');
  theme ??= (prefersDark.matches) ? 'dark' : 'default';
  applyTheme(theme);
}

function applyTheme(theme) {
  document.documentElement.className = theme;
}

window.setTheme = setTheme;

loadTheme();



let selector = document.getElementById('scheme');
  selector.addEventListener('click', event => {
    if (event.target == selector) { return; }
    window.setTheme(event.target.id);
});
:root.default { --bgr: #eee; --txt: #000; }
:root.light { --bgr: #ddc; --txt: #446; }
:root.dark { --bgr: #222; --txt: #a75; }
:root.blue { --bgr: #246; --txt: #eec; }
body { background: var(--bgr); color: var(--txt); margin: 1.5rem; }

#scheme button {
border: 1px solid red;
background: none;
color: inherit;
text-decoration: underline;
cursor: pointer;
}
    <h1> Select a theme to change the color scheme! </h1>
    <div id="scheme">
        <button id="auto">Auto</button>
        <button id="default">Default</button>
        <button id="light">Light</button>
        <button id="dark">Dark</button>
        <button id="blue">
        <svg width="20" height="20">
            <rect width="20" height="20" style="fill: lightgrey; stroke-width:1px; stroke: red;" />
        </svg>
        </button>
    </div>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

怀里藏娇 2025-02-13 12:49:32

SVG可能会阻止按钮接收和传播点击事件。您可以尝试:

button svg {
    pointer-events: none;
}

这允许单击“通过” SVG进入基础按钮

The SVG may be preventing the button from receiving and propagating the click event. You can try:

button svg {
    pointer-events: none;
}

This allows the click to go "through" the svg to the underlying button

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文