Cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Memory Fault when trying to update class for several objects at once

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?

 

Best Answer
0 Votes
4 REPLIES 4

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.

Peter McLennan
Gondwana Software
Best Answer
0 Votes

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

Best Answer
0 Votes

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.

Peter McLennan
Gondwana Software
Best Answer
0 Votes

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"

Best Answer
0 Votes