如何在初始页面加载之前加载 CSS 数据主题以防止主题之间闪烁?

Posted

技术标签:

【中文标题】如何在初始页面加载之前加载 CSS 数据主题以防止主题之间闪烁?【英文标题】:How to load a CSS data-theme before the initial page loads to prevent flickering between Themes? 【发布时间】:2020-07-16 23:29:59 【问题描述】:

我有一个数据主题,其中包含对原始 CSS 主题的大量修改。我已经有一个拨动开关在工作,我将它保存到 localStorage 以便记住它。但是,每当我在已启用深色主题的页面之间切换时,它会首先加载原始主题,但在整个页面加载后 应用深色主题。我希望页面之间的这种过渡是无缝的。

我正在使用 Node.js 并为 Web 应用程序表达。

我的数据主题修改大约有 200 行。这是数据主题的简短 sn-p:

[data-theme="dark"] html 
  background-color: #111111 !important;
  transition: 0.3s;


[data-theme="dark"] .bg-light 
  background-color: #333 !important;
  transition: 0.3s;


[data-theme="dark"] .bg-white 
  background-color: #000 !important;
  transition: 0.3s;


[data-theme="dark"] .bg-black 
  background-color: #eee !important;
  transition: 0.3s;


[data-theme="dark"] .topbar 
  background-color: #2196f3 !important;
  color: #2a1e37 !important;
  transition: 0.3s;


[data-theme="dark"] .btn 
  background-color: #2196f3 !important;
  border: 1px solid #2196f3 !important;
  color: #2a1e37 !important;
  transition: 0.3s;

等等。它适用于我的大部分元素。

我的问题的一个例子显示在这个简短的 gif 中:

https://gyazo.com/d53e12b7b5ea5215659a59a67639ba37

目前,我有一个脚本可以确定是否在标签中应用深色主题或浅色主题。

function initTheme() 
      console.log("initTheme() invoked!");
    var darkThemeSelected =
      localStorage.getItem("darkSwitch") !== null &&
      localStorage.getItem("darkSwitch") === "dark";

    darkThemeSelected
      ? document.body.setAttribute("data-theme", "dark") 
      : document.body.removeAttribute("data-theme");

    if (darkThemeSelected)
      document.getElementById("darkModeText").innerHTML=`Turn Lights On`;
      document.getElementById("darkModeIcon").className="zmdi zmdi-brightness-5";
    
    else 
      document.getElementById("darkModeText").innerHTML=`Turn Lights Off`;
      document.getElementById("darkModeIcon").className="zmdi zmdi-brightness-3";
    
  

正如您所看到的,我正在修改一些尚不存在的元素,因为它们存在于正文中。如何在加载之前实现深色主题?我正在使用 node.js 和 express。

【问题讨论】:

这还有用吗?在 CSS 中,如果最后一个规则具有相同的特异性,则它们获胜。假设您的 Express 服务器也提供 HTML,您需要相应地切换 <link rel="stylesheet" /> 标记。为了更好地工作,将主题的偏好(浅色/深色)存储在客户端的 cookie 中并使用 Express 读取它(cookie 总是随请求发送)。 有什么好处? localStorage 不是 cookie 吗? 不,localStorage 保留在客户端上(但在浏览器关闭后仍然存在 - 与 sessionStorage 不同)。 【参考方案1】:

您可以在初始化页面时禁用过渡

var element = document.getElementById('body');

function toggleTransition() 
  element.classList.toggle('dark');


function toggleNoTransition() 
  element.classList.add('disabled-transition');
  element.classList.toggle('dark');
  setTimeout(function() 
    element.classList.remove('disabled-transition');
  , 300)
.body 
  background: white;
  width: 100%;
  height: 100px;
  padding: 20px;
  transition: 0.3s;

.btn 
  background-color: black;
  border: 1px solid black;
  color: white;
  transition: 0.3s;


.dark.body 
  background: black;
  transition: 0.3s;


.dark .btn 
  background-color: #2196f3 !important;
  border: 1px solid #2196f3 !important;
  color: #2a1e37 !important;
  transition: 0.3s;


.disabled-transition,
.disabled-transition * 
  transition: none !important;
<div id="body" class="body">
  <button onClick="toggleTransition()" class="btn">toggle tranisition</button>
  <button onClick="toggleNoTransition()" class="btn">toggle no-tranisition</button>
</div>

【讨论】:

我不认为转换是问题。这是在初始页面加载之前加载 css 主题。 你确定初始化黑暗主题是在加载之前吗?在您的示例中,通过 javascript 初始化深色主题,但在 javascript 之前呈现浅色主题 我认为轻主题是在 javascript 之前呈现的,因为我在客户端更改了主题。我的问题是如何制作,以便可以首先呈现暗模式主题 在 HTML 页面中插入带有 initTheme 的

以上是关于如何在初始页面加载之前加载 CSS 数据主题以防止主题之间闪烁?的主要内容,如果未能解决你的问题,请参考以下文章

如何实时防止图像大小调整(页面加载期间)

如何防止css关键帧动画在页面加载时运行?

如何在父主题css之后加载wordpress子主题css

AngularJS 在用户选择时切换 css 主题

每次加载应用程序时,如何防止 Firestore 加载整个用户数据

加载数据后如何防止滚动视图滚动到网络视图?