JS странное поведение style.display с загрузчиком перед интенсивным фрагментом кода - PullRequest
1 голос
/ 24 сентября 2019

У меня есть веб-страница, где пользователь может выбрать некоторые пункты меню.Каждый вариант занимает несколько секунд, чтобы его можно было загрузить, обработать и показать.Поэтому в течение этого времени я пытаюсь показать загрузчик 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>

Короче длинная история, загрузчик показывает после "кода наложения".Для меня это абсолютно бессмысленно, и я не знаю, как продолжить.Любая помощь приветствуется.Большое вам спасибо.

С уважением,

Héctor

PD: консоль показывает такие сообщения, как: [Нарушение] Обработчик клика занял 4370 мс

1 Ответ

0 голосов
/ 24 сентября 2019

Эта часть JavaScript работает синхронно.

Вам необходимо поместить интенсивный код также в setTimeout.

Это потому, что изменения в DOM произойдут после того, как JavaScript вернется и завершится.

Пожалуйста, найдите здесь исправленный пример (с ниндзя, потому что я не запустил ваш 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>

Надеюсь, это поможет вам и даст достаточно объяснений.

...