Javascript 像 alert() 函数一样停止页面执行
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6807799/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Stop page execution like the alert() function
提问by Royi Namir
When I write alert('Hello')
, the page execution stops and waits for approval to continue.
当我写时alert('Hello')
,页面执行停止并等待批准继续。
I have a divsetup to display as a fake alert, using HTML - this div
has an 'OK' button.
我有一个使用 HTML 显示为假警报的 div设置 - 这div
有一个“确定”按钮。
I want the page to stop its execution (just like alert does) until the user click 'OK'.
我希望页面停止执行(就像警报一样),直到用户单击“确定”。
Is it possible ?
是否可以 ?
采纳答案by T.J. Crowder
You can't. Only the special built-ins can do that. For a while there was the showModalDialog
special built-in that let you specify a URI for the content and thus customize it, but it was never widely supported and is now deprecated even by browsers that once supported it.
你不能。只有特殊的内置插件才能做到这一点。有一段时间有一个showModalDialog
特殊的内置功能,可以让您为内容指定一个 URI 并因此对其进行自定义,但它从未得到广泛支持,现在甚至被曾经支持它的浏览器弃用。
Instead, make your current alerting function that uses the div
accept a callback for when the alert is closed (or return a promise that's settled when it's closed), to allow you to continue processing.
相反,让您当前使用div
接受回调的警报函数在警报关闭时使用回调(或返回在关闭时已解决的承诺),以允许您继续处理。
So for instance, if your code used to use alert
and work like this:
因此,例如,如果您的代码过去使用alert
和工作如下:
function foo() {
var x;
x = doSomething();
alert("Alert! Alert!");
doSomethingAfterTheAlertIsCleared(x);
doAnotherThingAfterward();
}
...you'd change it to:
...你会改变它:
function foo() {
var x;
x = doSomething();
fakeAlert("Alert! Alert!", function() {
doSomethingAfterTheAlertIsCleared(x);
doAnotherThingAfterward();
});
}
Note that now all the code that followed the alert is in a function, whose reference we pass into the fakeAlert
. The foo
function returns while the fake alert is still showing, but eventually the user dismisses the fake alert and our callback gets called. Note that our callback code has access to the locals in the call to foo
that we were processing, because our callback is a closure (don't worry if that's a fairly new and/or mysterious term, closures are not complicated).
请注意,现在警报之后的所有代码都在一个函数中,我们将其引用传递到fakeAlert
. 该foo
函数在假警报仍在显示时返回,但最终用户解除假警报并调用我们的回调。请注意,我们的回调代码可以访问foo
我们正在处理的调用中的局部变量,因为我们的回调是一个闭包(不要担心这是一个相当新和/或神秘的术语,闭包并不复杂)。
Of course, if the only thing following the alert is a single function call that doesn't take any arguments, we could just pass that function reference directly. E.g., this:
当然,如果警报之后的唯一事情是不带任何参数的单个函数调用,我们可以直接传递该函数引用。例如,这个:
function foo() {
doSomething();
alert("Alert! Alert!");
doSomethingAfterTheAlertIsCleared();
}
becomes:
变成:
function foo() {
doSomething();
fakeAlert("Alert! Alert!", doSomethingAfterTheAlertIsCleared);
}
(Note that there are no ()
after doSomethingAfterTheAlertIsCleared
-- we're referring to the function object, not calling the function; fakeAlert
will call it.)
(请注意,没有()
after doSomethingAfterTheAlertIsCleared
- 我们指的是函数对象,而不是调用函数;fakeAlert
将调用它。)
In case you're not sure how fakeAlert
would call the callback, it would be within the event handler for the user "closing" the alert div, and you just call the argument for the callback just like you do with any other reference to a function. So if fakeAlert
receives it as callback
, you call it by saying callback();
.
如果您不确定如何fakeAlert
调用回调,它将在用户“关闭”警报 div 的事件处理程序中,您只需调用回调的参数,就像对函数的任何其他引用一样. 因此,如果将fakeAlert
其作为接收callback
,则通过 say 来调用它callback();
。
回答by Vlad Mysla
Yes it's possible, i did inaccurate and not very well tested demo which does this.
是的,这是可能的,我做了不准确且没有经过很好测试的演示来做到这一点。
Main concept:
主要概念:
- in this example we have method Login.Try() which is executing Login.Proceed() method. Login.Proceed() makes AJAX query and we would like to wait for its execution, but don't want bind any handlers (just wait for it as window.alert() does)
- instead of direct function's execution Login.Proceed, we use async() and await() methods (like in C#)
- when we need to "pause" script and wait for something, we stop method execution using throw, and parse caller's function, to run its second part when waited (async) method has completed its execution.
- 在这个例子中,我们有方法 Login.Try() 正在执行 Login.Proceed() 方法。Login.Proceed() 进行 AJAX 查询,我们想等待它的执行,但不想绑定任何处理程序(只需像 window.alert() 那样等待它)
- 我们使用 async() 和 await() 方法,而不是直接执行函数 Login.Proceed(就像在 C# 中一样)
- 当我们需要“暂停”脚本并等待某事时,我们使用 throw 停止方法执行,并解析调用者的函数,以在等待(异步)方法完成执行时运行其第二部分。
What was left out of scope:
超出范围的内容:
- Clean code
- Test solution for different browsers
- Save/Restore local variables
- Not works for loops.
- 干净的代码
- 不同浏览器的测试方案
- 保存/恢复局部变量
- 不适用于循环。
Demo:
演示:
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script>
Login.Try(); // START!! START!! START!!
var Login = {
Url: "http://xxxx",
Try: async(this, function (T) {
console.log('before login');
//var success = call(this, Login.Proceed); // normal call
var success = await(this, Login.Proceed); // that we want!
console.log('after login');
console.log('success ' + success);
}),
Proceed: function (callback) {
console.log('before ajax');
$.ajax({
url: this.Url,
context: document.body
}).done(function () {
console.log('after ajax');
callback("role=admin");
});
}
}
function async(T, method){
console.log('before async create');
return function () { return method.apply(T); };
console.log('after async create');
};
function await(T, method) {
var fn = arguments.callee.caller.toString();
var pos = fn.indexOf('await(');
var allBeforeAwait = fn.substring(0, pos);
var pos1 = fn.indexOf('await(');
pos1 = fn.indexOf(',', pos1) + 1;
var pos2 = fn.indexOf(')', pos1);
var cc = fn.substring(pos1, pos2);
pos = allBeforeAwait.lastIndexOf(';');
var allBeforeCall = allBeforeAwait.substring(0, pos + 1) + "}";
var callResult = allBeforeAwait.substring(pos + 1);
var result = 10;
var allAfterCall = "("+fn.substring(0, fn.indexOf(")")) + ",V){" + callResult + "V;";
pos = fn.indexOf(')', pos) + 2;
allAfterCall = allAfterCall + fn.substring(pos)+")";
//uncomment to see function's parts after split
//console.debug(allBeforeCall);
//console.debug(cc);
//console.debug(allAfterCall);
method.apply(T, [function (value) {
console.log('ajax response ' + value);
eval(allAfterCall).apply(T, [T, value]);
} ]);
throw "";
};
</script>
Hope this demo will inspire you with some ideas.
希望这个演示能激发你的一些想法。
Also, you can take a look on http://blogs.msdn.com/b/rbuckton/archive/2011/08/15/promise-js-2-0-promise-framework-for-javascript.aspx
回答by Répás
It's not possible like the alert, but you can make things to look like an alert.
不可能像警报那样,但您可以使事情看起来像警报。
For example you make a function which calls functions. :) Then you make a function with a huge IF.
例如,您创建了一个调用函数的函数。:) 然后你用一个巨大的 IF 创建一个函数。
window.callfunction = function (f, a, b) /* function name, arguments, boolean*/
{
var handler = window[f];
if (typeof handler === 'function') {
handler(a, b);
} else {
alert("No function like that mate, sry.");
}
}
function deleteAfterConfirm(a, b) /* arguments, boolean */
{
if (b == true) {
alert("i can delete, confirmed.");
alert(a);
return false;
}
magicConfirm(a);
}
function magicConfirm(a) {
/**
modals, popovers, etc, anything you want,
**/
$("#confirmModal").modal("show");
/**
and put the function's name to the binding element's data
**/
$("#returntrue").data("call", arguments.callee.caller.name);
$("#returntrue").data("arguments", a);
/**
the element like OK button in the alert
calls the magicConfirm function's caller function
with true, which is the deleteAfterConfirm, and
because the bool is true, it will alert i can delete...
**/
$("#returntrue").bind("click", function () {
callfunction($(this).data("call"), $(this).data("arguments"), true);
});
}
$(document).ready(function () {
$("#deleteAfterConfirm").on("click", function () {
deleteAfterConfirm("variable which is needed later.");
});
});
So now you can use the deleteAfterConfirm function like a function with alert() or confirm(), because it's recalling the other part if itself.
所以现在你可以像使用带有alert() 或confirm() 的函数一样使用deleteAfterConfirm 函数,因为它正在调用其他部分,如果它自己。
Not the best method, but this can somehow replace the confirms and alerts for a better looking version. This is a way of the fake alertism :)
不是最好的方法,但这可以以某种方式替换确认和警报以获得更好看的版本。这是假警觉的一种方式:)
Have fun - R
玩得开心-R
回答by ykaragol
You cando it with Promise API. This is just about dividing your code and placing some lines in an action listener. Here is the sample code:
您可以使用 Promise API 来实现。这只是分割您的代码并在动作侦听器中放置一些行。这是示例代码:
In this example, there are two buttons. Clicking first button starts a code and the rest of your code will be placed on promise.then
function.
在本例中,有两个按钮。单击第一个按钮启动代码,其余代码将放在promise.then
函数上。
Html Code:
html代码:
<body>
<button id='startButton' onclick='start();'>Start Button</button>
<button id='targetButton'>Target Button</button>
</body>
Script Code:
脚本代码:
<script>
function start(){
console.log('first log'); //put your div displayer code here
let promise = new Promise(function(resolve, reject) {
console.log('promise started');
let targetButton = document.getElementById('targetButton');
targetButton.addEventListener("click",function(){
resolve();
});
});
promise.then(function() {
console.log('second log'); //put the rest of your code
});
}
</script>
You will see first log
and promise started
just after triggering start button. second log
will be displayed after you click the target button.
您将在触发开始按钮后看到first log
和promise started
。second log
单击目标按钮后将显示。
The resources for Promise API:
Promise API 的资源:
回答by Jasmeen
You can use following code to pause execution for long period of time.
您可以使用以下代码长时间暂停执行。
function PauseExcecution() {
//Do some stuff
sleep(1000);
//Do some stuff...}
function sleep(milliseconds) { var start = new Date().getTime(); for (var i = 0; i < 1e7; i++) { if ((new Date().getTime() - start) > milliseconds){ break; } } }
function PauseExecution() {
//做一些事情
sleep(1000);
//做一些事情...}
function sleep(milliseconds) { var start = new Date().getTime(); for (var i = 0; i < 1e7; i++) { if ((new Date().getTime() - start) > milliseconds){ break; } } }
回答by KingK
I think this is possible using basic JavaScript. You could have the fake button set like this:
我认为使用基本的 JavaScript 是可能的。你可以像这样设置假按钮:
<button id="fakeButton" value="not" onclick="fakeButtonValChange()">OK</button>
Then:
然后:
function fakeButtonValChange() {
var fakebuttonval = document.getElementById("fakeButton").value;
document.getElementById("fakebutton").value =
"clicked"
if (fakebuttonval == "clicked") {
*place stuff to show div here (i'm not good with css and that stuff)*
}
回答by Apoorv
Use `Bootstap' modal
使用‘Bootstap’模式
Then remove close button and disable model window hide by using below code
然后使用以下代码删除关闭按钮并禁用模型窗口隐藏
$('#myModal').modal({backdrop: 'static', keyboard: false})
Bind your function and close event to OK button of that modal window.
将您的函数和关闭事件绑定到该模式窗口的 OK 按钮。