09-13-2021 20:26
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

09-13-2021 20:26
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
when trying to implement theming on my clockface, I discovered you can change the class of an object using js, and wrote this function
function switchTheme(theme) {
for (let i = 0; i < 60; i++) {
let line = document.getElementById("line"+i);
line.class = theme;
}
}
attempting to use this function yields "Error 12 Critical glue error" along with "Memory fault (stack overflow?)".
it works for lower values of i, which implies to me that this is a bug.
for example, doing something like this technically works
function switchTheme(theme) {
function _switch(start, end) {
for (let i = start; i < end; i++) {
document.getElementById("line"+i).class = theme;
}
}
setTimeout(() => {_switch(0, 20)}, 0)
setTimeout(() => {_switch(20,40)}, 300)
setTimeout(() => {_switch(40,60)}, 600)
}
but since I'm trying to use it to switch between a light and dark theme, taking over half a second to switch the theme is obviously not ideal, and will cause the clockface to crash if the button is clicked too quickly.
I could add a variable to keep track of when it's switching, and to try and work around that, but that would make an already extremely ugly solution even uglier.
is there a standard solution for switching the classes of many objects quickly?

- Labels:
-
bug
-
clockface
-
device
-
JavaScript
09-13-2021 20:37
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post


09-13-2021 20:37
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
This may be irrelevant, but getElementById() can be slow. getElementsByClassName() can be faster. Also, don't search the entire document if you can avoid it.
Gondwana Software

09-13-2021 21:01
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

09-13-2021 21:01
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
I believe I've implemented both of your suggestions here, let me know if I haven't.
function switchTheme(oldTheme, theme) {
lines.getElementsByClassName(oldTheme).forEach((line) => {
line.class=theme
})
}
it still results in the glue error and memory fault mentioned above

09-13-2021 21:25
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post


09-13-2021 21:25
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
I'm afraid that's exactly what I had in mind.
If the style change only involves attributes that could be applied to a parent SVG element (eg, fill against a <svg>), you could try seeing if the lines would inherit the class change if you just changed the parent's .class.
Gondwana Software

09-13-2021 21:50
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

09-13-2021 21:50
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
unfortunately not. they're actually gradientRects, "line" as a name may be a bit misleading there.
it's also unfortunate that descendant and child selectors aren't implemented, otherwise I could do something like this
.dark .line {
(...)
}
.light .line {
(...)
}
<svg id="lines" class="dark">
<gradientRect id="line0" class="line"/>
(...)
</svg>
and then simply swap the class of "lines"

