【问题标题】:How to set cursor to 'wait' for duration of script running?如何在脚本运行期间将光标设置为“等待”?
【发布时间】:2021-10-08 04:31:55
【问题描述】:

我想在一个冗长的 javascript 函数运行时将光标样式设置为“等待”,然后再重置为正常。

我认为这可能就足够了:

document.body.style.cursor = 'wait';
// long scripting here
document.body.style.cursor = 'auto';

但是 .. 如果我将光标移动到(例如)<input>,那么光标会更改为适当的类型,例如'文本'。 (通过控制台中的各个命令进行测试)。

我确实找到了这个similar question,它设置了一个css规则
html.wait, html.wait * { cursor: wait !important; }
并通过这个 js 使用它:

document.querySelector("html").classList.add("wait");
// long scripting here
document.querySelector("html").classList.remove("wait");

.. 但是.. 在脚本运行时它似乎没有启动。

【问题讨论】:

  • jsfiddle.net/gwmc1b65 它似乎在这里工作..
  • 在这里也可以使用脚本切换类~jsfiddle.net/12jLm5w6/1
  • @phil 啊,您已将添加/删除类脚本步骤与 setTimeout/await 分开。如果它是在做真正的忙碌工作,这仍然有效吗?
  • 我不确定。也许尝试用一个巨大的for 循环替换它(对不起,我真的不知道如何在 JS 中模拟同步繁忙的工作)
  • 那么问题解决了吗?如果不是,请提供“此处为长脚本”的示例,可能存在问题

标签: javascript css


【解决方案1】:

设置一个空闲延迟,让 JS 可以将 CPU 释放回浏览器,以便它有机会进行重绘(或其他任何调用)。

const DELAY_FOR_REFRESH = 25; // milliseconds
document.querySelector("html").classList.add("wait");
setTimeout( () => {
  // long scripting here
  document.querySelector("html").classList.remove("wait");
}, DELAY_FOR_REFRESH);

在有限的测试中,DELAY_FOR_REFRESH 需要至少超过 20 毫秒 - 更快,观察到的行为是浏览器在长脚本开始之前不会重新绘制/更新。

注意。将光标重置回“自动”需要在 setTimeout() 功能结束时发生(而不是在它之后)。


我对这里发生的事情的心理模型是这样的:

  1. DOM 已更新,更改为设置“等待”光标
  2. 浏览器尚未更新窗口,因为浏览器没有空闲的 CPU 周期
  3. JS 为以后安排工作
  4. CPU 空闲,等待计划任务完成
  5. 浏览器现在有空闲 CPU,经过足够的时间后,它决定重新绘制/对步骤 1 中的 DOM 进行任何更改
  6. 计划任务开始
  7. 计划任务最终完成,包括重置光标

【讨论】:

  • 如果您知道“repaint-thingy”、“scheduled task”等的正确技术术语,请进行编辑。
  • 使用requestAnimationFrame()会更好吗?
猜你喜欢
  • 2022-06-15
  • 1970-01-01
  • 2010-12-06
  • 1970-01-01
  • 2018-04-08
  • 2011-02-11
  • 2012-06-16
  • 2011-09-29
相关资源
最近更新 更多