我正在尝试在JavaScript中重新创建基本提示框的行为,以便我可以设置它的样式。基本上,我希望能够调用一个函数(window.vars.prompt
)并让它提示用户,然后返回用户输入的值。我希望一切都能同步发生,这样我就可以通过函数调用它并让它返回给调用者。
我到目前为止冻结了程序,然后崩溃了。我知道为什么,但我不知道如何解决它。有人解决了吗?
谢谢!
(function () {
window.vars.userHasResponded = false
window.vars.userResponse = ""
window.vars.prompt = function(displayMsg) {
$(".input").html(`<div class='prompt'><h2>${displayMsg}</h2><div class="input"><input id="promptValue"/></div><div class="promptContros"><button>ok</button><button>cancel</button></div></div>`)
while (!window.vars.userHasResponded) {
if (window.vars.userResponse)
return window.vars.userResponse;
}
}
window.vars.confirmPrompt = function() {
$(".prompt").html("")
window.vars.userResponse = $("#promptValue").val()
window.vars.userHasResponded = window.vars.userResponse != "";
}
})()
该框的HTML存储在一个带有输入
类的div中答案 0 :(得分:1)
我正在尝试在javascript中重新创建基本提示框的行为...我希望所有内容同步发生,以便我可以通过函数调用它并让它返回给调用者。 / p>
你不能这样做。 prompt
,alert
,confirm
和beforeunload
处理程序是基于浏览器的JavaScript世界中唯一的同步用户界面,您无法对其进行样式设置。在您自己的UI小部件中复制该行为是不可能的。
您自己的小部件将 异步。
在对您提出的问题的评论中:
为什么while循环不起作用?
因为循环通过忙等待占用主UI线程。基于浏览器的JavaScript中的用户事件排队等待线程返回浏览器(如果用户甚至首先看到更新的DOM元素)。忙碌等待使当前任务保持活动状态,这意味着队列中的事件等待您的任务完成。
相反,让你的prompt
和这样的回报成为承诺。然后,在正常函数中使用它看起来像这样:
prompt(/*...*/)
.then(result => {
// ...use the result
});
...或async
function中的这种情况:
const result = await prompt(/*...*/);
(为简洁省略了错误处理。)
答案 1 :(得分:1)
我希望一切都能同步发生
不幸的是,这是不可能的 - 脚本编写者无法编写自己的基本上阻止的API,直到解决它们而不完全冻结浏览器,他们只能调用一些具有这种特殊属性的特殊内置方法。因此,您的while
循环的线程将永远运行,阻止confirmPrompt
运行。线程永远不会结束,因此永远不会给confirmPrompt
一个运行的机会。
尝试使用Promises。 await
虽然不是同步的,但看起来比使用.then
更加同步。