停止 JavaScript 执行而不锁定浏览器
您是否能够在不锁定浏览器的情况下停止 JavaScript 执行?通常停止执行的方法是执行无限 while()
循环,但对于 FireFox,它会锁定浏览器,直到循环结束。
您对此有何看法?
我正在尝试重写 window.confirm()
以使用 HTML 实现我自己的对话框。我这样做是为了不必更改现有代码(这是一个相当大的代码库)。
我需要能够停止执行以允许用户输入;依次返回一个布尔值,就像标准确认函数一样:
if (confirm("..."))
{
// user pressed "OK"
}
else
{
// user pressed "Cancel"
}
更新
据我所知;这不能使用 setTimeout()
或 setInterval()
来完成,因为这些函数异步执行提供给它们的代码。
Are you able to halt JavaScript execution without locking up the browser? The way you would normally halt execution is to do an infinite while()
-loop, but in the case of FireFox, it locks up the browser until the loop has ended.
What's your take on this?
I am trying to override window.confirm()
to implement my own dialog using HTML. I am doing this so I don't have to change existing code (it's a pretty big code-base).
I need to be able to halt execution to allow user-input; to in turn return a boolean like the standard confirm function does:
if (confirm("..."))
{
// user pressed "OK"
}
else
{
// user pressed "Cancel"
}
Update
To my knowledge; this cannot be done using setTimeout()
or setInterval()
since these functions execute the code thats given to them asynchronously.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
confirm()
prompt()
和alert()
是特殊函数——它们从 JavaScript 沙箱调用到浏览器,然后浏览器暂停 JavaScript 执行。您不能做同样的事情,因为您需要将功能构建到 JavaScript 中。我不认为有一个很好的方法可以在不进行一些重组的情况下更换替代品:
confirm()
prompt()
andalert()
are special functions--they call out of the JavaScript sandbox into the browser, and the browser suspends JavaScript execution. You can't do the same thing, since you need to build your functionality into JavaScript.I don't think there's a great way to drop in a replacement without doing some restructuring along the lines of:
使用回调或使您的代码仅适用于 Firefox。在支持JavaScript 1.7及更高版本的Firefox中,您可以使用yield语句来模拟您想要的效果。我为此目的创建了一个名为 async.js 的库。 async.js 的标准库包含一个确认方法,可以这样使用:
Either use callbacks or make your code Firefox-only. In Firefox with support for JavaScript 1.7 and higher, you can use the yield statement to simulate your desired effect. I have created a library for this purpose called async.js. The standard library for async.js includes a confirm method, which can be used as such:
您无法在 JavaScript 中停止事件线程,因此您必须解决该问题,通常是使用回调函数。这些函数稍后运行,但可以像 JavaScript 中的任何其他对象一样传递。您可能通过 AJAX 编程熟悉它们。因此,例如:
将转换为:
其中
customConfirm
现在接受一个问题并将结果传递给它作为参数的函数。如果您使用按钮实现 DOM 对话框,则将事件侦听器连接到“确定”和“取消”按钮,并在用户单击其中之一时调用回调函数。You cannot stop the event thread in JavaScript, so instead you have to work around the problem, usually by using callback functions. These are functions that are run at a later time, but can be passed around like any other object in JavaScript. You might be familiar with them from AJAX programming. So, for example:
Would be converted into:
where
customConfirm
now takes a question and passes the result to the function it takes as an argument. If you implement a DOM dialog with a button, then connect an event listener to the OK and CANCEL buttons, and call the callback function when the user clicks on one of them.JavaScript 语言有一个扩展,称为 StratifiedJS。它在每个浏览器中运行,并且允许您做到这一点:停止一行 JavaScript 代码而不冻结浏览器。
您可以通过在网页中包含 Oni Apollo ( http://onilabs.com/docs ) 来启用分层 JavaScript就像:
你的代码看起来像这样:
There is an extension to the JavaScript language called StratifiedJS. It runs in every browser, and it allows you to do just that: halting one line of JavaScript code without freezing the browser.
You can enable Stratified JavaScript e.g. by including Oni Apollo ( http://onilabs.com/docs ) in your webpage like:
Your code would look like this:
通常停止执行的方式几乎不应该是无限的 while 循环。
将您的工作分成几个部分,您可以使用 SetTimeout
将其更改
为:
the way you normally halt execution should hardly ever be an infinite while loop.
break up your work into parts, that you call with SetTimeout
change this:
to this:
我认为没有任何方法可以在您自己的 JavaScript 中合理地重新创建confirm() 或prompt() 的功能。它们是“特殊的”,因为它们被实现为对本机浏览器库的调用。您实际上无法在 JavaScript 中执行此类模式对话框。
我见过各种 UI 库,它们通过在页面顶部放置一个元素来模拟效果,看起来和效果很不错。行为类似于模式对话框,但它们是使用异步回调实现的。
您将必须修改现有库,而不是替换 window.confirm。
I don't think there's any way to reasonably re-create the functionality of confirm() or prompt() in your own JavaScript. They're "special" in the sense of being implemented as calls into the native browser library. You can't really do a modal dialog of that sort in JavaScript.
I have seen various UI libraries that simulate the effect by putting an element on top of the page, that looks & acts like a modal dialog, but those are implemented using async callbacks.
You will have to modify the existing library, rather than replacing window.confirm.
我尝试使用紧密循环 这个。我需要减慢本机事件的速度(据我所知,这是无法异步重新架构的同步等待的唯一用例)。有很多循环示例声称不会锁定浏览器;但它们都不适合我(浏览器没有锁定,但它们阻止它做我最初等待的事情),所以我放弃了这个想法。
接下来我尝试了这个 - 存储和重播该事件,这似乎也是不可能跨浏览器的。然而,根据事件以及您需要的灵活性,您可以接近。
最后我放弃了,心里感觉好多了;我找到了一种方法,可以让我的代码正常工作,而不必减慢本机事件的速度。
I tried using tight looping for this. I needed to slow down a native event (which AFAIK is the only use case for a synchronous wait that can't be re-architected asynchronously). There are lots of example loops out there that claim not to lock up the browser; but none of them worked for me (the browser didn't lock up, but they prevented it from doing the thing I was waiting for in the first place), so I abandoned the idea.
Next I tried this - storing and replaying the event, which seems to be impossible cross-browser too. However depending on the event and how flexible you need to be, you can get close.
In the end I gave up, and feel much better for it; I found a way to make my code work without having to slow down the native event at all.