style.display 在密集代码片段之前加载器的 JS 怪异行为

JS weird behaviour of style.display with loader before intensive code fragment

我有一个网页,用户可以在其中 select 从菜单中选择一些选项。每个选项都需要几秒钟才能下载、处理和显示。所以在这段时间里,我尝试展示一个加载器 gif。但是我遇到了一些奇怪的问题,我被卡住了。

我创建了一个非常简单的 jsfiddle,删除除最小代码以外的所有内容以重现问题:

$('#ActnBtn').click(function() {
  document.getElementById("loading").style.display = "block";
  console.log("loader should be showed");

  //Intensive code simulation, probably you should adjust the "times" value to the power of your device
  var times = 5000000000;
  for (let i = 0; i < times; i++) {
    var j = (i ^ 2 + 1) / (i - 1) ^ 2;
  }
  console.log("finished")

  setTimeout(function() {
    document.getElementById("loading").style.display = "none";
  }, 1000); 
  // 1sec timeout to be able to see the loader
  // document.getElementById("loading").style.display = "none" 
  // Without timeout loader isn't showed because "show" and "hide" happens at the same time
});
#loading {
  display: none;
  position: fixed;
  left: 0px;
  top: 0px;
  width: 100%;
  height: 100%;
  z-index: 9999;
  background: url(https://media.giphy.com/media/lrnlLO9o53qH44g7kC/giphy.gif) center no-repeat #fff;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id=loading></div>

<button id="ActnBtn" type="button">Do some intesive work</button>

长历史短,加载程序在"intesive code"之后显示。对我来说,这完全没有意义,我现在不知道如何继续。任何帮助表示赞赏。非常感谢。

此致,

赫克托

PD:控制台显示如下消息:[违规] 'click' 处理程序耗时 4370 毫秒

这部分 javascript 同步运行。

您需要将密集型代码也放在 setTimeout 中。

这是因为对 DOM 的更改将在 javascript returns 之后完成。

请在此处找到更正的示例(带有忍者,因为我没有得到您的 gif 运行),我将您的迭代放在计时器等函数中。

$('#ActnBtn').click(function() {
    document.getElementById("loading").style.display = "block";
          console.log("loader should be showed");
    setTimeout(function(){
    

    //Intensive code simulation, probably you should adjust the "times" value to the power of your device
      var times = 5000000000;
      for(let i=0; i<times; i++){
          var j = (i^2+1)/(i-1)^2;
      }
      console.log("finished")

      setTimeout(function(){document.getElementById("loading").style.display = "none";},1000); //1sec 
   },0);
});
#loading {
    display: none;
        position: fixed;
        left: 0px;
        top: 0px;
        width: 100%;
        height: 100%;
        z-index: 9999;
        background: url('https://loading.io//assets/img/pricing/ninja.gif') center no-repeat #fff;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id=loading></div>

<button id="ActnBtn" type="button">Do some intesive work</button>

我希望这对你有帮助并给出足够的解释。