我有一个页面有几个需要显示的加载旋转器。我把它们放在一个函数中,当我需要它们时,我就会调用它们(有一个相反的函数可以隐藏它们)。我想让我的spinners在materializecss选择框的变化事件中显示出来。ID在选择元素上。在这些spinners出现后,会有一个长期运行的javascript过程。这包括一些api调用和长期运行的循环。我的问题是,我无法让代码在运行javascript之前等待所有的spinners出现。我试过按照其他几个帖子的建议使用setTimeout和requestAnimationFrame,但脚本还是启动了,而且spinners迟迟没有出现。
物质化生成的HTML Snippet。
<div class="select-wrapper">
<input class="select-dropdown dropdown-trigger" type="text" readonly="true" data-target="select-options-262e9372-9f06-8033-4ddc-5ed565152b96">
<ul id="select-options-262e9372-9f06-8033-4ddc-5ed565152b96" class="dropdown-content select-dropdown" tabindex="0" style="">
<li class="disabled" id="select-options-262e9372-9f06-8033-4ddc-5ed565152b960" tabindex="0"><span>All Competitors</span></li>
<li id="select-options-262e9372-9f06-8033-4ddc-5ed565152b961" tabindex="0" class=""><span>Comp A</span></li>
<li id="select-options-262e9372-9f06-8033-4ddc-5ed565152b962" tabindex="0" class="selected"><span>Comp B</span></li>
<li id="select-options-262e9372-9f06-8033-4ddc-5ed565152b963" tabindex="0"><span>Comp C</span></li>
</ul>
<svg class="caret" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M7 10l5 5 5-5z"></path><path d="M0 0h24v24H0z" fill="none"></path></svg>
<select id="competitor" tabindex="-1">
<option value="" disabled="">All Competitors</option>
<option value="a" selected="">Comp A</option>
<option value="b">Comp B</option>
<option value="c">Comp C</option>
</select>
</div>
Spinner功能。
function showLoadingSpinners() {
$("#filtersSpinner").addClass("show");
$("#mapSpinner").addClass("show");
$("#tableSpinner").addClass("show");
$("#submitButton").prop("disabled", true);
if (listOfStuff.length >= maxStoresForPricing) {
$("#tooManyMessage").fadeIn();
}
}
尝试A:
$("#competitor").on("change", function () {
showLoadingSpinners();
secondStep();
function secondStep() {
if (!$("#filtersSpinner").hasClass("show")) {
window.requestAnimationFrame(secondStep);
} else {
doLotsOfStuff();
}
}
});
尝试B
$("#competitor").on("change", function () {
showLoadingSpinners();
setTimeout(function () {
doLotsOfStuff();
}, 350);
});
我建议使用Javascript工作 Promise
在你想做的事情上,更准确地说,这将是一个非常好的想法,与你的工作。Promise.all()
.
编辑下面的片段中有一个小例子供你检查。
const spinnerA = new Promise((resolve, reject) => {
setTimeout(() =>{
document.getElementById("textA").style.display = "block";
resolve(true);
},3000);
});
const spinnerB = new Promise((resolve, reject) => {
setTimeout(() =>{
document.getElementById("textB").style.display = "block";
resolve(true);
},3000);
});
Promise.all([spinnerA, spinnerB]).then(() => {
alert(document.getElementById("last").textContent);
});
#textA {
display: none;
}
#textB {
display: none;
}
#last {
display: none;
}
<div id="textA">text A</div>
<div id="textB">text B</div>
<div id="last">both text are in a visible state and you will see them once you close this alertbox </div>