等待所有dom更新完成

问题描述 投票:0回答:1

我有一个页面有几个需要显示的加载旋转器。我把它们放在一个函数中,当我需要它们时,我就会调用它们(有一个相反的函数可以隐藏它们)。我想让我的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 settimeout materialize requestanimationframe
1个回答
1
投票

我建议使用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>
© www.soinside.com 2019 - 2024. All rights reserved.