重建提示框行为

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.

你不能这样做。 promptalertconfirmbeforeunload 处理程序是基于浏览器的 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 更同步。