skip to Main Content

I am trying to implement theming on a web application. Currently there are several themes and a panel from which the user can change the theme.
I want to register an event and detect when the theme loads.
The code is as follows:

const link = document.createElement('link')
link.rel = 'stylesheet'
link.href="first-theme.css'
link.onload = () => console.log('Theme loaded')

document.head.append(link)

This works fine when the first theme is set and the link element is created.

However, the problem is when I try to change the theme.
When I change the theme, I don’t create a new link element, but rather update the href of the existing one.

function changeTheme(theme){
  link.href=theme
}

When I call changeTheme, the onload event is not fired again, even though the new file is loaded.

As a side note, this workflow works on the img tag

const img = document.createElement('img')
img.src='https://picsum.photos/200'
img.onload = () => console.log("Image loaded")

document.body.append(img)

setTimeout(() => img.src='https://picsum.photos/300', 1000)
setTimeout(() => img.src='https://picsum.photos/400', 2000)

The above code will print Image loaded for 3 times.

2

Answers


  1. Whilst I have never found a fix for this, I can suggest a workaround.

    Place an empty div element off screen and have each CSS file set it to a different size. You can then use the ResizerObserver API to detect when this element changes size as a proxy for the new stylesheet loading.

    Login or Signup to reply.
  2. Try to get the theme using fetch API and create a new CSSStyleSheet using replace() method:

    // response from fetch request
    const textContent= "body { font-size: 1.4em; } p { color: red; }";
    
    const stylesheet = new CSSStyleSheet();
    stylesheet
      .replace(textContent)
      .then(() => {
         document.adoptedStyleSheets = [stylesheet];
      })
      .catch((err) => {
        console.error("Failed to replace styles:", err);
      });
    
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search