【问题标题】:HTML element updated by JS only after a long function finishes, even if placed before仅在长函数完成后由 JS 更新的 HTML 元素,即使放在之前
【发布时间】:2019-10-16 19:34:21
【问题描述】:

问题如下:我想修改一个 h1(id="waiting"),然后执行一个需要几秒钟才能完成的函数(解决)。

function solveWrapper(table) {
        document.getElementById("waiting").innerHTML = "Wait please, Nurikabe is being solved...";
        alert("alert");
        var currentState = new State(table);
        solve(table, currentState);
    }

使用此代码,我在调用求解函数之前收到警报,但只有在该函数执行完成后才修改 h1 标记。有谁知道如何解决这一问题? 这是调用solveWrapper的按钮:

<button onclick="solveWrapper(grid);">Solve</button>

这是完整的代码:https://github.com/jackowski626/projects/blob/master/Nurikabe_SJ_Solver.html

【问题讨论】:

  • 将调用solve() 放入超时处理程序中
  • @Pointy 我将它设置为 5 秒超时,但它没有任何改变
  • 你能添加你用来调用函数的代码(solveWrapper)吗?也许还有另一个函数/代码正在进行更改,换句话说,元素正在正确更新
  • 您可以使用 callback 函数来实现,或者修改您的代码以返回 Promise。那应该可以解决。 (或 async await 语法。)
  • @LeonidasMenendez 它是通过 html 按钮调用的。这可能是问题

标签: javascript html


【解决方案1】:

在超时处理程序中调用solve()

function solveWrapper(table) {
    document.getElementById("waiting").innerHTML = "Wait please, Nurikabe is being solved...";
    var currentState = new State(table);
    setTimeout(function() {
      solve(table, currentState);
    }, 10);
}

浏览器推迟更新视图直到事件循环完成,除非他们别无选择。

【讨论】:

  • 我试过这个:``` setTimeout(solve(table, currentState), 5000); ```为什么错了?
  • 当你这样做时,函数被调用之前 setTimeout()被调用。
【解决方案2】:

我会说试试看:

function solveWrapper(table) {
  window.requestAnimationFrame(
    document.getElementById("waiting").innerHTML = "Wait please, Nurikabe is being solved..."
  );
  alert("alert");
  var currentState = new State(table);
  solve(table, currentState);
}

这个想法是requestAnimationFrame 应该会导致浏览器重绘并为您更新屏幕上呈现的内容。我认为问题在于您正在调用对 innerHTML 的更改,但它不会在浏览器中反映出来,直到它准备好执行此操作,即在它运行您的解决功能之后。

https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame

【讨论】:

  • requestAnimationFrame 期望它的参数是一个函数。您的意思是要将第三行包装在函数表达式中吗?
  • 是的,抱歉,window.requestAnimationFrame(() =&gt; { document.getElementById("waiting").innerHTML = "Wait please, Nurikabe is being solved..."} ); 虽然现在我想知道您是否可以将它包装在一个立即调用的函数中,而无需 requestAnimationFrame
猜你喜欢
  • 1970-01-01
  • 2013-04-09
  • 1970-01-01
  • 1970-01-01
  • 2019-11-18
  • 1970-01-01
  • 2019-11-14
  • 1970-01-01
  • 2022-11-10
相关资源
最近更新 更多