我写了下面的代码,并把它放在我的网站的每个页面的</body>
标签之前。它工作得很好,因为它把每个页面的背景变成黑色,文本变成白色,并记住这个设置,直到用户把它改回"白天模式"。
<script>
var body = $("body");
var day = $("#day");
var night = $("#night");
var dayLi = $("#day-li");
var nightLi = $("#night-li");
var panel = $(".panel");
if(localStorage.night == "on"){
body.addClass("night");
panel.addClass("night");
dayLi.show();
nightLi.hide();
}else{
body.removeClass("night");
panel.removeClass("night");
nightLi.show();
dayLi.hide();
}
night.click(function(){
body.addClass("night");
panel.addClass("night");
localStorage.setItem("night","on");
dayLi.show();
nightLi.hide();
});
day.click(function(){
body.removeClass("night");
panel.removeClass("night");
localStorage.night = "off";
nightLi.show();
dayLi.hide();
});
</script>
.night
类如您所料:
.night{
background-color: black;
color: white;
}
我遇到的问题是,在夜间模式下,夜间模式需要大约一秒钟才能生效,这意味着在每个页面加载上都有一个白色的闪光。
我尝试将上面的脚本放在页面的更高位置,但仍然在每次页面加载时首先显示白色。需要明确的是,在没有从数据库加载大量数据的页面上,白色的闪光非常短或几乎不存在。但是在从数据库加载大量数据的页面上,flash持续大约一秒钟。
这是可以修复的东西吗?
正如我所提到的,完全消除flash是不可能的,但是您可以通过在头部执行flash而不使用类(因为样式表是异步加载的)来大大减少flash。
在<body>
开始标签之后添加一个脚本,执行此逻辑:
<script>
if(localStorage.night == "on") {
document.body.style.backgroundColor = "#000"; // color of your choice
}
</script>
注意,你不能使用jquery,因为那时它还没有加载。这将最大限度地减少你的页面颜色错误的时间。
编辑:另一个可能的解决方案是使用CSS在服务器端进行更改,这应该具有相同的效果。问题在于,由于CSS文件是异步加载的,因此需要将样式呈现为inline。
为了防止前端出现未样式内容的Flash (FOUC),您可以使用"斗篷"技巧。AngularJS和VueJS都在单页应用中使用这种技术。
在你的HTML中,设置一个样式标签来隐藏你的<body>
。
<style>
body {
display: none;
}
</style>
然后,在您现有的代码中,甚至是一个独立的脚本中,您可以这样做:
$(function() {
$(body).css('display', 'initial');
});
这是有效的,因为嵌入的样式将首先运行,隐藏你的body元素。然后,一旦javascript加载完成,DOM也准备好了,脚本就会运行,揭开body的隐藏。
你可以通过将嵌入的样式更新为
来增强它,使其总是以黑色开始:body * {
display: none;
background: #000;
}
这将使body为黑色,并隐藏其所有子类。