javascript - DOM 背景颜色传播闪烁继承 Google Chrome 中的初始背景颜色,使用主题切换来重载主体背景颜色

标签 javascript jquery css background-color chromium

我目前正在为我的网站开发一个主题切换器,它使用 Javascript/jQuery 来使用由按钮切换的 lightmode()/darkmode() 函数来操纵 Body.bg 颜色。我想要做的是在主体背景颜色与淡入淡出之间创建无缝过渡。我已经制作并创建了它,但问题是当主题读取存储类型时,它会在 Chrome 和 Chrome Canary 中快速闪烁,但在 Safari 和 Catalina 的 Safari Tech Preview 中它可以无缝工作。

但是,当用户切换到白色然后单击导航链接时,我一直遇到一个问题,这会导致暗模式主题黑色闪烁。我的网站开始时启用了暗模式,body bg = #0a0a0a,但是当它切换到白色并更新存储时,它仍然继承了黑色 body - bg 最初在我的主题的 style.less 中设置。

如果我删除背景颜色,那么白色闪烁会发生在深色模式主题上,理想情况下,我的最终目标是创建无缝页面导航,而无需页面闪烁,以便在主体加载之前快速读取初始背景颜色,以便- 白色背景上的白色,黑色背景上的黑色不闪烁以造成视觉干扰。

我已经尝试了所有我能想出的解决办法,但找不到解决方案。它在 Safari 中工作,没有页面闪烁,但在 Chrome 中它仍然闪烁。我已经包含了视频链接,显示了我想使用 Google chrome 的 Safari 渲染器和 main.js 代码文件完成的工作。

Safari seamless transitioning with no blink

Safari - 无缝过渡

Chrome Canary

Chrome 和 Chrome Canary - 观察白色过渡时的闪烁。这很快但非常令人沮丧。

所以这是怎么回事?!问题是主题现在设置为白色,但初始 body - bg 颜色在 style.less 主题中是黑色的,它会在快速返回白色主题之前快速选择它。

当我在 Canary 中审核站点并以模拟的慢速 3G 运行它时没有闪烁,但是当它正常运行或在审核中以快速 3G 运行时会出现闪烁。我的假设是在加载之前在 body 上设置一个超时,但我尝试将其作为解决方法,但仍然闪烁。

我已经尝试创建存储在本地存储中的 key 用于我的存储并暂停正文加载,但到目前为止我找不到解决这个问题的方法:/

所以我想做的是阻止 body bg 颜色基于主题颜色基色闪烁白色或黑色而不闪烁。

感谢您花时间阅读我的问题!

document.addEventListener("DOMContentLoaded", function() {
document.body.style.backgroundColor = "inherit";

if (document.readyState === 'complete') {

if(lightmodeON == true) {
  $('body').css({background: "#FFF"});
  console.log('loading white bg');
}

if(lightmodeON == false) {
  $('body').css({background: "#0a0a0a"});
  console.log('loading black bg');
}
}


if (typeof (Storage) !=="undefined") {
if (localStorage.themepref == 1 ) {
  lightmode();
}
else {
  darkmode();
  localStorage.themepref = 2;
}

if(lightmodeON == true) {
  $('body').css({background: "#FFF"});
  console.log('loading fffwhite bg');
}

if(lightmodeON == false) {
  $('body').css({background: "#0a0a0a"});
  console.log('loading black bg');
}
}

这是我尝试变通的版本。

var clickDelay = false;
var themeType = -1;
var lightmodeON = false;


window.onload = function() {
  console.log('First');

  if (event.target.readyState === 'interactive') {

      $('body').css({ background: ''});
      document.body.style.backgroundColor = "inherit";

   if(lightmodeON == true) {
     $('body').css({background: "#FFF"});
       document.body.style.backgroundColor = "#FFF";
   }

   if(lightmodeON == false) {
     $('body').css({background: "#0a0a0a"});
       document.body.style.backgroundColor = "#0a0a0a";
   }
}
    overloadBG();
};


document.addEventListener("DOMContentLoaded", function() {
  document.body.style.backgroundColor = "inherit";

  if (document.readyState === 'complete') {

    if(lightmodeON == true) {
      $('body').css({background: "#FFF"});
      console.log('loading white bg');
    }

    if(lightmodeON == false) {
      $('body').css({background: "#0a0a0a"});
      console.log('loading black bg');
    }
  }


  if (typeof (Storage) !=="undefined") {
    if (localStorage.themepref == 1 ) {
      lightmode();
    }
    else {
      darkmode();
      localStorage.themepref = 2;
    }

    if(lightmodeON == true) {
      $('body').css({background: "#FFF"});
      console.log('loading fffwhite bg');
    }

    if(lightmodeON == false) {
      $('body').css({background: "#0a0a0a"});
      console.log('loading black bg');
    }
  }



});

window.addEventListener('beforeunload', function (e) {
  $('body').css({ background: ''});

  if(lightmodeON == true) {
    $('body').css({background: "#FFF"});
      document.body.style.backgroundColor = "#FFF";
  }

  if(lightmodeON == false) {
    $('body').css({background: "#0a0a0a"});
      document.body.style.backgroundColor = "#0a0a0a";
  }

  document.body.style.backgroundColor = "inherit";
  overloadBG();
  
});

window.onbeforeunload = function () {
  //FUCK YOU BLINK
  //$('body').css({ background: 'none'});
  $('body').css({ background: ''});
    document.body.style.backgroundColor = "";

  if (typeof (Storage) !=="undefined") {
    if (localStorage.themepref == 1 ) {
        localStorage.themepref = 1;
        lightmode();
    }
    else {
      darkmode();
      localStorage.themepref = 2;
    }
  }

}

document.onreadystatechange = function() {


    $('body').css({ background: ''});
    document.body.style.backgroundColor = "transparent";

    if (event.target.readyState === 'interactive') {
        console.log('interactive');

             if(lightmodeON === true) {
               $('body').css({background: "#FFF"});
             }

             if(lightmodeON === false) {
               $('body').css({background: "#0a0a0a"});
             }
      }

      if (event.target.readyState === 'loading') {

          $('body').css({ background: ''});

       if(lightmodeON == true) {
         $('body').css({background: "#FFF"});
         $("body").css("cssText", "background: #FFF !important;");
       }

       if(lightmodeON == false) {
         $('body').css({background: "#0a0a0a"});
         $("body").css("cssText", "background: #0a0a0a !important;");
       }
    }

最佳答案

当 DOMContentLoaded 触发时,浏览器可能已经绘制了您页面的背景。

这是一个无限期地重新加载页面的演示,一定要在看完后点击“隐藏结果”,它可能会使您的计算机占用一些 CPU 资源(但不会占用网络资源)。

/* 
  We use an iframe to avoid making real network requests 
  Below is the HTML content of this iframe
*/

const content = `<!DOCTYPE html>
<html>
  <head>
    <style>
      /* default bg color */
      body { background: red; }
    </style>
    <script>
      document.addEventListener('DOMContentLoaded', e => {
        document.body.style.backgroundColor = 'green';
        location.reload() // infinite reload...
      });
    <\/script>
  </head>
  <body>
    <div>
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi blandit cursus orci ut maximus. Phasellus pharetra lobortis pellentesque. Pellentesque et lacus et lorem facilisis ultrices. Maecenas sed ultricies nisi. Suspendisse feugiat finibus justo, id consectetur turpis aliquam ac. Proin sit amet laoreet velit. Nullam felis lectus, commodo imperdiet mollis in, ullamcorper eget tortor. Nullam at metus non diam faucibus aliquam. Vestibulum eu maximus risus, vitae elementum justo. Fusce commodo lacus a augue lobortis, quis ornare odio gravida. Quisque ultrices tempus tellus, vitae pulvinar est rutrum in. Duis ante erat, placerat sit amet imperdiet vitae, facilisis non mauris. Integer eu ex sapien.</p>
      <p>Morbi porttitor justo eu sodales efficitur. Integer ut suscipit libero, sed dapibus velit. Vestibulum laoreet neque ac odio consequat, a suscipit arcu tristique. Curabitur tempor, nisl eu porttitor feugiat, nibh lorem laoreet massa, ut porta tellus augue accumsan metus. Suspendisse sed venenatis neque. Aliquam non justo in tortor dictum suscipit. Duis eu lectus eu dui placerat luctus. Etiam et volutpat diam, nec ullamcorper tellus. Nullam nibh dui, bibendum a ipsum et, elementum tempor mi. Maecenas ut eros eu sem malesuada tincidunt. Aenean fermentum sit amet augue quis vulputate. Vivamus commodo pellentesque purus rhoncus suscipit. Proin et enim vel ipsum vulputate mollis venenatis ut enim. Curabitur eget velit mollis, luctus sem at, aliquam est. Donec quis elit erat. Nullam facilisis lorem nisl, a luctus purus tristique vel.</p>
      <p>Donec in magna at ante mollis sodales ac vitae mauris. Aliquam condimentum ligula nulla, scelerisque cursus neque consequat quis. Fusce vestibulum nisi vitae ipsum venenatis, a pharetra diam tempus. Aenean maximus enim orci, quis mollis neque sollicitudin et. Quisque viverra ipsum vitae magna varius, id ornare justo dictum. Quisque eleifend magna ac congue dignissim. Duis eu volutpat quam, quis placerat tellus. Pellentesque felis mi, imperdiet eu semper vel, hendrerit sit amet ex.</p>
    </div>
  </body>
</html>
`;
frame.src = URL.createObjectURL(new Blob([content], {type: 'text/html'}));
<iframe id="frame" widht="500" height="500"></iframe>

要解决此问题,请将您的脚本移动到 <body> 的顶部并设置初始 <body> 尽快从存储中取出颜色。
在附加其他事件之前,您仍然可以等待文档准备就绪。

/* 
  We use an iframe to avoid making real network requests 
  Below is the HTML content of this iframe
*/

const content = `<!DOCTYPE html>
<html>
  <head>
    <style>
      /* default bg color */
      body { background: red; }
    </style>
  </head>
  <body>
    <!-- move inside <body> -->
    <script>
      // first retrieve from Storage
      // const lightModeOn = locaStorage.getItem('lightmode') === "1";
      // StackSnippets don't allow Storage...
      const lightModeOn = true;
      // set directly the body's style, we're in so we don't need to wait, it's already available
      document.body.style.backgroundColor = 'green';
      // then wait for DOMContentLoaded if you wish to add listeners to other events
      document.addEventListener('DOMContentLoaded', e => {
      // $('.toggle').on('input', switchLight);

      // just to demonstrate it works
      location.reload();
   });
      
    <\/script>

    <div>
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi blandit cursus orci ut maximus. Phasellus pharetra lobortis pellentesque. Pellentesque et lacus et lorem facilisis ultrices. Maecenas sed ultricies nisi. Suspendisse feugiat finibus justo, id consectetur turpis aliquam ac. Proin sit amet laoreet velit. Nullam felis lectus, commodo imperdiet mollis in, ullamcorper eget tortor. Nullam at metus non diam faucibus aliquam. Vestibulum eu maximus risus, vitae elementum justo. Fusce commodo lacus a augue lobortis, quis ornare odio gravida. Quisque ultrices tempus tellus, vitae pulvinar est rutrum in. Duis ante erat, placerat sit amet imperdiet vitae, facilisis non mauris. Integer eu ex sapien.</p>
      <p>Morbi porttitor justo eu sodales efficitur. Integer ut suscipit libero, sed dapibus velit. Vestibulum laoreet neque ac odio consequat, a suscipit arcu tristique. Curabitur tempor, nisl eu porttitor feugiat, nibh lorem laoreet massa, ut porta tellus augue accumsan metus. Suspendisse sed venenatis neque. Aliquam non justo in tortor dictum suscipit. Duis eu lectus eu dui placerat luctus. Etiam et volutpat diam, nec ullamcorper tellus. Nullam nibh dui, bibendum a ipsum et, elementum tempor mi. Maecenas ut eros eu sem malesuada tincidunt. Aenean fermentum sit amet augue quis vulputate. Vivamus commodo pellentesque purus rhoncus suscipit. Proin et enim vel ipsum vulputate mollis venenatis ut enim. Curabitur eget velit mollis, luctus sem at, aliquam est. Donec quis elit erat. Nullam facilisis lorem nisl, a luctus purus tristique vel.</p>
      <p>Donec in magna at ante mollis sodales ac vitae mauris. Aliquam condimentum ligula nulla, scelerisque cursus neque consequat quis. Fusce vestibulum nisi vitae ipsum venenatis, a pharetra diam tempus. Aenean maximus enim orci, quis mollis neque sollicitudin et. Quisque viverra ipsum vitae magna varius, id ornare justo dictum. Quisque eleifend magna ac congue dignissim. Duis eu volutpat quam, quis placerat tellus. Pellentesque felis mi, imperdiet eu semper vel, hendrerit sit amet ex.</p>
    </div>
  </body>
</html>
`;
frame.src = URL.createObjectURL(new Blob([content], {type: 'text/html'}));
<iframe id="frame" widht="500" height="500"></iframe>

关于javascript - DOM 背景颜色传播闪烁继承 Google Chrome 中的初始背景颜色,使用主题切换来重载主体背景颜色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57666206/

相关文章:

jquery - 如何在 jQuery 中的 mustache 模板中添加一个带有图片数量结束增量的类?

javascript - 在 InfoBubble.js 中使用 fancyBox 和 Google Maps API

javascript - 文本甚至不使用 typed.js 输入

javascript - 既然八进制转义已被弃用,我应该如何在 CSS 中输入 Unicode 字符?

javascript - 如何从 redux store 获取状态的最新值?

javascript - Node js 的谷歌端到端加密

javascript - 在javascript中打印元素宽度

javascript - 在javascript中设置模式对话框

javascript - 如何创建有关如何使用网页的教程

javascript - 执行 WebSocket/AJAX 应用程序的 'soft-refresh'(仅 JS 和 CSS)