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>
我希望这对你有帮助并给出足够的解释。
我有一个网页,用户可以在其中 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>
我希望这对你有帮助并给出足够的解释。