javascript - 等待所有 dom 更新完成

标签 javascript settimeout materialize requestanimationframe

我有一个页面,其中有几个需要显示的加载微调器。我将它们放在需要它们时调用的函数中(有一个相反的函数用于隐藏它们)。我希望我的微调器显示在 MaterializeCSS 选择框的更改事件上。 ID 位于选择元素上。这些旋转器出现后,立即会出现一个长时间运行的 javascript 进程。这由一些 api 调用和长时间运行的循环组成。我的问题是我无法让代码在运行 JavaScript 之前等待所有旋转器显示。我已经尝试了 setTimeout 和 requestAnimationFrame 正如其他几篇文章所建议的那样,但脚本无论如何都会启动并且旋转器会延迟出现。

由 Materialize 生成的 HTML 片段:

<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>

微调功能:

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>

关于javascript - 等待所有 dom 更新完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61546480/

相关文章:

javascript - 导航栏不粘

JavaScript Onclick window.open 在 IE 中无法正常工作

javascript - 了解 JavaScript 计时器线程问题

jquery - Margin Auto 渲染到 Margin 0px

javascript - 5 秒后弹出 Bootstrap 模态窗口

javascript - 循环中的多个设置超时

html - 在另一个 div 中垂直居中一个按钮在它自己的 div 中

javascript - jQuery if else 语句和 data()

javascript - 如何在 meteor js中获取点击事件的值(value)?

javascript - 控制速度和改变球的颜色