需要在 OS 中更改 dark/light 模式以强制刷新外部 SVG 文件
Need dark/light mode change in OS to force refresh of external SVG files
我的网站使用许多外部 SVG 文件,这些文件在 SVG 文件本身中有自己的 <style>
元素。我在主网站 CSS 和 中有暗模式媒体查询,在 SVG 文件自己的样式中:@media (prefers-color-scheme:light)
和 @media (prefers-color-scheme:dark)
在初始加载或硬刷新时,一切都按预期工作,网站 CSS 和 SVG CSS 根据系统 OS 是否加载适当的样式设置为深色或浅色模式。
但是,如果我在 OS 中切换模式,只会更新网站 CSS,不会更新外部 SVG 文件的 CSS。
所以,我需要完全重新加载缓存的 SVG 图像,或者以某种方式刷新 SVG CSS。
我在 javascript 中设置了一个事件侦听器,可以正确检测到 OS 模式更改,但我不知道如何在 OS 时触发 SVG 刷新dark/light 模式已更改。我到处搜索,但不确定如何以最简单、最优雅的方式执行此操作。
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', e => {
// WHAT GOES HERE TO REFRESH SVGs TO CORRECTLY REFLECT OS MODE?
});
window.location.reload(true);
不会硬重新加载缓存文件。我不确定 cache.delete
在这里是否合适,或者我将如何使用它来强制重新加载所有 SVG 图像 (<img src="whatever.svg"/>
)。也许我忽略了另一种方法。
感谢您的帮助。
几行 javascript 就可以了。首先,在页面加载时,识别所有 SVG 图像并确定当前 prefers-color-scheme
主题。然后,检测该主题何时更改并将动态缓存破坏程序附加到这些文件名,这会强制 SVG 重新加载。
// Dark mode changes needs cache refresh for external SVG file CSS.
allImg = document.querySelectorAll('img[src$=".svg"');
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
thisMode = 'dark';
} else {
thisMode = 'light';
}
window.matchMedia('(prefers-color-scheme: '+ thisMode + ')').addEventListener('change', e => {
allImg.forEach(img => {
imgTime = Date.now();
newImgSrc = img.src + '?' + imgTime;
img.src = newImgSrc;
});
});
更新原始答案 12/13/21。现在强制重新加载 SVG 的 cachebuster 仅在模式更改后调用,而不是在每次页面加载时调用。
21 年 12 月 19 日更新:此解决方案不适用于 Safari(a known bug Safari 不遵守 SVG 文件中的首选颜色方案媒体查询 CSS)。对于 Safari,我编写了额外的 JS 来检测页面加载时的 Safari,使用上面的首选颜色方案条件,并且,如果 OS 是暗模式,则将所有 SVG 文件名从“image.svg”替换为“ image-dark.svg”,调用每个 SVG 的浅色或深色版本。当 OS dark/light 主题更改时,它还会在 Safari 中重新加载页面。如果 Apple 修复了这个错误,我可以使用上面更简单的解决方案。
我的网站使用许多外部 SVG 文件,这些文件在 SVG 文件本身中有自己的 <style>
元素。我在主网站 CSS 和 中有暗模式媒体查询,在 SVG 文件自己的样式中:@media (prefers-color-scheme:light)
和 @media (prefers-color-scheme:dark)
在初始加载或硬刷新时,一切都按预期工作,网站 CSS 和 SVG CSS 根据系统 OS 是否加载适当的样式设置为深色或浅色模式。
但是,如果我在 OS 中切换模式,只会更新网站 CSS,不会更新外部 SVG 文件的 CSS。
所以,我需要完全重新加载缓存的 SVG 图像,或者以某种方式刷新 SVG CSS。
我在 javascript 中设置了一个事件侦听器,可以正确检测到 OS 模式更改,但我不知道如何在 OS 时触发 SVG 刷新dark/light 模式已更改。我到处搜索,但不确定如何以最简单、最优雅的方式执行此操作。
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', e => {
// WHAT GOES HERE TO REFRESH SVGs TO CORRECTLY REFLECT OS MODE?
});
window.location.reload(true);
不会硬重新加载缓存文件。我不确定 cache.delete
在这里是否合适,或者我将如何使用它来强制重新加载所有 SVG 图像 (<img src="whatever.svg"/>
)。也许我忽略了另一种方法。
感谢您的帮助。
几行 javascript 就可以了。首先,在页面加载时,识别所有 SVG 图像并确定当前 prefers-color-scheme
主题。然后,检测该主题何时更改并将动态缓存破坏程序附加到这些文件名,这会强制 SVG 重新加载。
// Dark mode changes needs cache refresh for external SVG file CSS.
allImg = document.querySelectorAll('img[src$=".svg"');
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
thisMode = 'dark';
} else {
thisMode = 'light';
}
window.matchMedia('(prefers-color-scheme: '+ thisMode + ')').addEventListener('change', e => {
allImg.forEach(img => {
imgTime = Date.now();
newImgSrc = img.src + '?' + imgTime;
img.src = newImgSrc;
});
});
更新原始答案 12/13/21。现在强制重新加载 SVG 的 cachebuster 仅在模式更改后调用,而不是在每次页面加载时调用。
21 年 12 月 19 日更新:此解决方案不适用于 Safari(a known bug Safari 不遵守 SVG 文件中的首选颜色方案媒体查询 CSS)。对于 Safari,我编写了额外的 JS 来检测页面加载时的 Safari,使用上面的首选颜色方案条件,并且,如果 OS 是暗模式,则将所有 SVG 文件名从“image.svg”替换为“ image-dark.svg”,调用每个 SVG 的浅色或深色版本。当 OS dark/light 主题更改时,它还会在 Safari 中重新加载页面。如果 Apple 修复了这个错误,我可以使用上面更简单的解决方案。