基于JavaScript+Cookie的主题切换页面FOUC问题解决求助
解决主题切换的FOUC(无样式内容闪烁)问题
问题根源
你当前使用window.onload触发主题切换,这个事件要等页面所有资源(图片、样式、脚本)加载完成才会执行。此时浏览器已经渲染了默认的theme-dark.css主题,之后才替换为Cookie中存储的主题,因此必然出现闪烁。
解决方案步骤
1. 修正Cookie读取函数的语法错误
你的getCookie函数存在两处多余括号,会导致JS运行报错,先修正:
function getCookie(name) { var cookies = document.cookie.split(";"); for (var i = 0; i < cookies.length; i++) { var ck = cookies[i].trim().split("="); if (ck[0] === name) return ck[1]; } return false; }
2. 把主题切换逻辑移到<head>内联执行
放弃window.onload,直接在HTML的<head>中添加内联脚本,在浏览器解析主题CSS标签前就加载正确的主题文件,从根源避免闪烁:
<link rel="stylesheet" type="text/css" href="/css/style.css"> <script> function getCookie(name) { var cookies = document.cookie.split(";"); for (var i = 0; i < cookies.length; i++) { var ck = cookies[i].trim().split("="); if (ck[0] === name) return ck[1]; } return false; } // 读取Cookie,设置主题路径(和按钮路径统一) var viewmode = getCookie("viewmode"); var themeHref = viewmode || "/css/theme/theme-dark.css"; // 动态创建主题CSS标签 var link = document.createElement('link'); link.id = 'swap'; link.rel = 'stylesheet'; link.type = 'text/css'; link.href = themeHref; document.head.appendChild(link); </script> <link rel="stylesheet" type="text/css" href="/css/calendar.css">
3. 统一主题路径
注意你的默认主题路径是/css/theme-dark.css,但切换按钮中的路径是/css/theme/theme-dark.css,两者必须统一(建议全部使用按钮中的路径格式),否则会出现加载错误。
4. 保留修正后的切换函数
把以下修正后的函数放在外部JS文件或页面底部的脚本中,确保切换按钮能正常调用:
function swapStylesheet(sheet) { document.getElementById('swap').setAttribute('href', sheet); setCookie("viewmode", sheet, 30); } function setCookie(name, value, days) { var d = new Date(); d.setTime(d.getTime() + days * 24 * 60 * 60 * 1000); document.cookie = name + "=" + value + "; expires=" + d.toUTCString() + "; path=/"; } function getCookie(name) { var cookies = document.cookie.split(";"); for (var i = 0; i < cookies.length; i++) { var ck = cookies[i].trim().split("="); if (ck[0] === name) return ck[1]; } return false; }
为什么之前的方案无效?
- HTML前加载CSS:这个方案其实适用,但你误解了逻辑——不是写一个包含3种主题的CSS,而是根据Cookie动态加载对应主题的CSS,也就是我们上面实现的:在
<head>中先判断Cookie,再加载正确的主题文件,而非先加载默认主题再替换。 - preload CSS:preload仅会提前下载资源,但你仍用
window.onload切换主题,浏览器还是会先渲染默认主题,再替换,无法解决时机问题。 - 控制容器可见性:如果脚本执行时机过晚,页面仍会先显示内容再隐藏,或显示时机不对,不如直接让浏览器从一开始就加载正确的主题。
内容的提问来源于stack exchange,提问作者Developer
相关产品推荐
相关产品推荐

