When I write alert('Hello')
, the page execution stops and waits for approval to continue.
I have a div setup to display as a fake alert, using HTML - this div
has an 'OK' button.
I want the page to stop its execution (just like alert does) until the user click 'OK'.
Is it possible ?
One of the nice things about the built-in JavaScript alert is that - unlike virtually anything else in JavaScript - it's synchronous. It's completely blocking, and no other code will execute until it's been dismissed.
One useful function that's native to JavaScript is the alert() function. This function will display text in a dialog box that pops up on the screen. Before this function can work, we must first call the showAlert() function. JavaScript functions are called in response to events.
Select the monitor that generated the alert and click Reset Health on the toolbar. Close the Health Explorer and the State view. Refresh the alerts view. If the alert is still listed, click the alert and then click Close Alert in the Actions pane.
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.
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.
So for instance, if your code used to use alert
and work like this:
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).
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.)
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();
.
Yes it's possible, i did inaccurate and not very well tested demo which does this.
Main concept:
What was left out of scope:
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With