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
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.Try to get the theme using fetch API and create a new
CSSStyleSheet
usingreplace()
method: