重建提示框行为
rebuild prompt-box behaviour
我正在考虑尝试在 JavaScript 中重新创建基本提示框的行为,以便我可以设置它的样式。本质上,我希望能够调用一个函数 (window.vars.prompt
) 并让它提示用户,然后 return 用户输入的值。我希望一切都同步发生,这样我就可以通过一个函数调用它并将它 returned 给调用者。
我目前所做的是冻结程序,然后使其崩溃。我知道为什么,但我不知道如何解决它。有人修吗
谢谢!
(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 中,其中 class 为 input
I'm looking at trying to recreate the behaviour of a basic prompt box in javascript...I want everything to happen synchronously, so that I can call it via a function and have it returned to the caller.
你不能这样做。 prompt
、alert
、confirm
和 beforeunload
处理程序是基于浏览器的 JavaScript 世界中唯一的同步 UI,您不能设置样式他们。不可能在您自己的 UI 小部件中复制该行为。
您自己的小部件将 是异步的。
在对您提出的问题的评论中:
how come that while loop doesn't work?
因为循环通过忙等待占用了主线程 UI。基于浏览器的 JavaScript 中的用户事件排队等待线程返回给浏览器(如果用户甚至首先看到更新的 DOM 元素)。您的忙等待使当前任务保持活动状态,这意味着队列中跟随它的事件等待您的任务完成。
相反,让您的 prompt
和 return 有一个承诺。然后,在普通函数中使用它看起来像这样:
prompt(/*...*/)
.then(result => {
// ...use the result
});
...或者像这样 async
function:
const result = await prompt(/*...*/);
(为简洁起见省略了错误处理。)
I want everything to happen synchronously
不幸的是,这是不可能的 - 脚本编写者无法编写自己的 API,基本上阻止直到他们在不完全冻结浏览器的情况下解决,他们只能调用 一些特殊的内置方法,这些方法具有特殊的 属性。照原样,您的 while
循环的线程将永远 运行,从而阻止 confirmPrompt
永远 运行。线程永远不会结束,因此永远不会 confirmPrompt
有机会 运行.
尝试改用 Promises。 await
,虽然不是同步的,但 看起来 比使用 .then
更同步。
我正在考虑尝试在 JavaScript 中重新创建基本提示框的行为,以便我可以设置它的样式。本质上,我希望能够调用一个函数 (window.vars.prompt
) 并让它提示用户,然后 return 用户输入的值。我希望一切都同步发生,这样我就可以通过一个函数调用它并将它 returned 给调用者。
我目前所做的是冻结程序,然后使其崩溃。我知道为什么,但我不知道如何解决它。有人修吗
谢谢!
(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 中,其中 class 为 input
I'm looking at trying to recreate the behaviour of a basic prompt box in javascript...I want everything to happen synchronously, so that I can call it via a function and have it returned to the caller.
你不能这样做。 prompt
、alert
、confirm
和 beforeunload
处理程序是基于浏览器的 JavaScript 世界中唯一的同步 UI,您不能设置样式他们。不可能在您自己的 UI 小部件中复制该行为。
您自己的小部件将 是异步的。
在对您提出的问题的评论中:
how come that while loop doesn't work?
因为循环通过忙等待占用了主线程 UI。基于浏览器的 JavaScript 中的用户事件排队等待线程返回给浏览器(如果用户甚至首先看到更新的 DOM 元素)。您的忙等待使当前任务保持活动状态,这意味着队列中跟随它的事件等待您的任务完成。
相反,让您的 prompt
和 return 有一个承诺。然后,在普通函数中使用它看起来像这样:
prompt(/*...*/)
.then(result => {
// ...use the result
});
...或者像这样 async
function:
const result = await prompt(/*...*/);
(为简洁起见省略了错误处理。)
I want everything to happen synchronously
不幸的是,这是不可能的 - 脚本编写者无法编写自己的 API,基本上阻止直到他们在不完全冻结浏览器的情况下解决,他们只能调用 一些特殊的内置方法,这些方法具有特殊的 属性。照原样,您的 while
循环的线程将永远 运行,从而阻止 confirmPrompt
永远 运行。线程永远不会结束,因此永远不会 confirmPrompt
有机会 运行.
尝试改用 Promises。 await
,虽然不是同步的,但 看起来 比使用 .then
更同步。