如何使用jQuery实现“夜间模式”没有在每个页面加载时闪烁的白色

How to use jQuery to implement "night mode" without flashing white on each page load?

本文关键字:加载 白色 闪烁 实现 jQuery 何使用 夜间模式 模式      更新时间:2023-09-26

我写了下面的代码,并把它放在我的网站的每个页面的</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为黑色,并隐藏其所有子类。