Home > Enterprise >  Why does is SVG not as "hot" as TEXT, when triggering click action for a theme change? (Ja
Why does is SVG not as "hot" as TEXT, when triggering click action for a theme change? (Ja

Time:06-13

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>

CodePudding user response:

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

  • Related