Is it possible to make a custom alert/confirm/prompt that have the same behaviour as native javascript windows (without using callbacks/asynchronous events)?
Ex.:
if(mytest == true){
myCustomMsgWindow('message'); //Pause execution
//do something
}
I tried this once but dint works for confirm window because it must return a value.
You can make custom ones but their behavior will not be the same.
Because in the browsers these boxes pause the execution thread, and resumed by user action. you can not pause the execution thread, this is implicit.
However there are some workaround which may behave almost similar. You can try that
BootBox
No, you cannot write JS code that blocks (pauses execution) waiting for user input on without alert or confirm. You have to listen for events within your dialog asynchronously (through events)
The solution is use callbacks as you have already mentioned, not sure why you don't want to use that.
Related
I am working on an ionic project, and as part of this project, the user will have to complete a timed task. They have to answer a multiple choice question in 15~ seconds, otherwise they fail the task.
I currently have a timeout in the background, which will call function "evaluate" in the background, and disable the multiple choice answer buttons. This function is also called by the click of one of the multiple choice answer buttons.
Is there a danger of an edge case where the user selects the button just as the timeout calls the evaluate function, leading to the function being called twice? How can I avoid this?
As far as I known, there is no way to have a "race condition" in a web browser session, basically because each tab in a web browser runs in a single thread, so your logic will runs in a single runloop. You can use this fact to implement a flag indicating what happens first, but (honestly) this is pretty ugly.
I think the most elegant solution should be to make the function evaluate idempotent, that way, you don't care if is called several times.
You could have a variable named something like "eval_running" that you check in your evaluate function. If it is false, you set it to true and proceed evaluating. If it is true, you return from the function without evaluation. When you display the next task, you reset the variable to false.
That would prevent any kind of race condition. The time frame in which a double execution could occur depends on how long the eval function is working in the background. Chances are, you do not need to worry about this.
The best approach in this scenario is not very complicated. So the timeout trigger and also the submit button are calling the same evaluatefunction.
All you need to do is this. Disable the submit button immediately at the opening of the function and then write whatever you want to do. So if the timeout calls the function first, the button will be disabled before executing the operations, and the user cannot click the button anymore. If the button is clicked first, then it goes as it should and there's no complication here.
Other javascript is changing the value of an input and I was wondering if there was a way to detect the change.
This question has nothing to do with Keyup or Change. This is not being typed in by the user it is being changed by other javascript though various actions of the user.
When changing an event programatically, you can trigger a change event to make sure event handlers that are attached to the element are fired. jQuery has a trigger() method to do this:
$('#elementID').on('change', function() {
alert( this.value );
});
$('#elementID').val('some new value').trigger('change');
The quick run-down of what I am going to say is: there is no way other than to modify the third-party scripts to output stuff, or to use setInterval (costly).
The bottom line of this issue is a simple one, that does not appear to be so at first: How can you get your scrips to communicate with each other?
When a script modifies the value of an input through JS methods (i.e. not user input), they have to go through specific hoops to get the "change" event to fire (they can fire it manually by calling it, which most devs never do and is easily forgotten when writing code). In practice, people tend to rely on the observation events (user-defined ones) to track code changes. This is very similar to DOM events - you bind callbacks to your script, which allow you to tap callbacks in that will fire whenever your scripts do something interesting (like modifying inputs. This is just one example). You then teach your scripts and developers to fire events on useful stuff using the callbacks to notify other scripts.
A great library for this is Postal, which is originally a Node library. jQuery also has an event system you can tap into. However, if you want to roll your own, all you have to read into is the Observer design pattern. It is trivial: you bind a function to your object to pick up callbacks, and another to fire them. Whenever you change the thing, you fire the callback. Simples.
Failure to do so means setInterval. Sucks, but there you go :-(
I'm looking for a way to capture HTML of objects that are rendered on rollover. An example would be:
Mouse over object to get popup
Press button or key to pause js (to prevent mouse out trigger)
Right click and inspect element to get HTML
Does anyone know of a way to do this?
To your main question, there are two ways to pause the execution of a Javascript thread:
Hit a breakpoint in a debugger
Insert an alert() into the javascript thread and when it fires, it will suspend the execution of that javascript thread until the alert dialog is dismissed.
You haven't described the environment you're operating in and what types of modifications you can or can't make to the host page for us to advise more specifically.
To approach the problem differently, to capture some dynamically inserted HTML there are other strategies. For example, you can use your own javascript (like a bookmarklet) to attach an event handler to the mouse over. You can then set a timer that will watch for when the dynamically generated HTML seems to be present and grab a copy of it. Keep in mind that javascript is single threaded so your own timer will only run when the other javascript thread is waiting for user input, but if the general model is that it pops something up on mouseover and then waits for additional mouse events, then this could work.
yes, <object onmouseover="functionPopup();" onmouseout="functionWrap();">
then place your onkeyup-event to detect the button/key.
The trick is to leave the functionWrap on the object ALONE!!! and OVERWRITE this function functionWrap() (that is referenced by object's onmouseout) with the updated instructions (this works pretty good crossbrowser -even older ones-, since this uses the traditional event model :P ).
Happy tweaking!!
just wanted to know if it is programatically possible to halt the execution of script the same way javascript function "confirm" does. "confirm" stops further execution of script until user input, i want to acheieve same thing for BlockUI plugin of Jquery.
No, you cannot.
confirm, like the alert function, is a modal dialog, which is nothing more than a child window that requires users to interact with it before they can return to operating the parent application, thus preventing the workflow on the application main window.
Javascript has no sleep-ing mechanism. If you want to stop the execution of a script... it's only possible by executing another script that is memory/CPU expensive (such as an infinite loop) that will freeze the browser (thus stopping the targeted script from executing), but that kind of defeats the purpose.
If you know what you want to do, you can organize your code in such a manner that you can simulate the sleep process.
A good way of doing that is using callbacks combined with timeouts:
function f1(callback){
// do some stuff
// decide how much you want to wait
setTimeout(callback,how_much_you_want_to_wait);
}
I don't think its possible... the best you can do is,
show an overlay div which prevents any other user interactions on page
show your html popup in front of the overlay
in the code, use callbacks or 'jquery binders' or 'event listers' to execute the rest of the code
A rough example could be,
function showDialog(fn){
$('#overlay').show()
$('#dialog').show().click(fn); // ideally bind the click to the close button of the dialog
}
now, to show the dialog,
// code before the dial
showDialog(function(){
// execute rest of the code
})
Javascript has no sleep function that may be available in other languages. The best you can do is a setTimeout.
You could possibly do while true style loop but that will just spike CPU usage which is usually not encouraged.
This question already has answers here:
How to create a custom "confirm" & pause js execution until user clicks button?
(6 answers)
Closed 6 years ago.
I want to simulate a block dialog like window.alert(), window.confirm(), or window.prompt() with DIV+JavaScript. It seems easy using a callback function. But I want to block the process while the confirm dialog is shown.
That is to say, I want to define a function like:
var Alert = function(){ balabala };
which returns true or false after I click OK or Cancel.
EDIT:
For now I defined a function called Confirm() and now I have to call it like
Confirm(*callback*);
and in the implementation I show a dialog like confirm and when OK is clicked the callback will be executed. I wonder whether it is possible to rewrite it so that I can call it like
if(Confirm()) {
callback();
} else {
balabala;
}
You can't block the user from using their browser IE switching tabs and doing other things on them before they come back to yours, like an alert() call does. But you can block them from using anything on your page until they answer the question. You can just fill the entire body with an absolute positioned div that has a z-index greater than the rest of your page, and give your popup a z-index one higher than that and center it.
Of course a user can still use things like Chrome developer tools or Firebug to remove your blocking div, so it's not a secure thing.
Edit I misread your question. You don't care about blocking the page visually but are wanting to make the popup's return value synchronous with the rest of your script instead of asynchronous with a callback. I'm not sure how to go about that.
Maybe this will be of use to you: https://developer.mozilla.org/en/Code_snippets/Threads#Waiting_for_a_background_task_to_complete
Unfortunately, there's no way to simulate synchronous code calls with just JavaScript. You can create pure DOM-based dialogs, but in order to have code execute when they close, you'd need to have it accept a callback or return a Promise. Unfortunately, this doesn't make for the most clean code.