I've edited the default alert() function like this:
window.alert = function(str){
//custom alert
}
Essentially, the new function will show an HTML <div> modal.
Backstory:
I want to answer to this question because I am having a problem. The alert is hidden and will show when the custom alert function is called. So the custom alert is basically showing the element and changing it's text. Therefore, when I have multiple alert() calls, only the last message is displayed! :(
But, unlike the default alert box. It of course won't pause the webpage until the alert goes away like the default alert() function.
Is it possible to imitate this "pause the webpage" behavior?
Also, is there another way other then using setTimeout() to check if isCustomAlertOpen == true to delay another custom alert from triggering until the current one is dismissed?
Edit:
Is there a way to queue up the custom alerts?
I don't mind jQuery, but I thought it might be overpowered here.
My question title is bad. Can someone think of a better title for me please?
There is no way to block the execution because JavaScript is asynchronous (except obviously 3 modal functions and XmlHttpRequest).
For the same reason, you can't wait for a previous alert to be closed, but you can use events to create a stack of alerts using this pattern:
window.alert = (function() {
var stack = [];
var showNextAlert = function() {
var div = document.createElement("div");
/* Here, configure the div, show the string from stack[0] and add it to the document ... */
var okButton = /* ... */;
okButton.addEventListener("click", function() {
div.parentNode.removeChild(div);
stack = stack.slice(1);
if(stack.length > 0) {
showNextAlert();
}
});
}
return function(msg) {
stack.push(msg);
if(stack.length == 1) {
// Show it immediately if the stack is empty
showNextAlert();
}
};
})();
You should also use another name for this function instead of changing native properties (here window.alert).
Is it possible to imitate this "pause the webpage" behavior?
The answer to this is no. There are ways to block the ui (sync ajax call, long loop etc). But you wouldn't be able to stop these when the user has click the ok button.
A better approach would be to restructure the code so that it didn't run synchronously. Ie you wouldn't need to block the ui while waiting for the user.
Also, is there another way other then using setTimeout() to check if isCustomAlertOpen == true to delay another custom alert from triggering until the current one is dismissed?
One way to do this is: instead of setting a flag in one place and checking it repeatedly in another. You can use the concept of events. One part of code is waiting for an event to be triggered and another part triggers it. There is a library in jQuery which can do this for you or you could read up on it and write your own.
Related
I have a script with a function that checks out a document's first story. When I run this, a dialog pops up asking whether I want to update the text to the latest version. Since this function runs several times per run of the script, I want to suppress this dialog by replying yes every time. Is there a way to automatically say yes to these dialogs as they come up, or just suppress them with an automatic response?
function doccheckout(doc) {
// get the main story
var stories = doc.stories
var story = stories.firstItem()
// check out the main story
story.checkOut()
}
The same thing happens when I close out the document with document.checkIn(), so I'd like to suppress that one as well, but I assume any solution to the first part will be applicable to the second.
Relevant popups
Try to disable the user interaction:
app.scriptPreferences.userInteractionLevel = UserInteractionLevels.NEVER_INTERACT;
// your code here
//
// at the end of your script reset it to the default
app.scriptPreferences.userInteractionLevel = UserInteractionLevels.INTERACT_WITH_ALL;
so I am working on a really small chrome extension. There is a webpage and I want to click the buttons on this webpage. After I click all of them I want to click the next page button and keep doing the same thing.
I have no problem finding the buttons or the nextpagebutton. I am also able to do it using setInterval functions but I feel like it is kind of a hacky way to do this.
The below code is what I have so far
function clickButtons(){
var followButtons = $('.buttonClass');
var numberOfButtons = followButtons.length;
for(var i=0; i<numberOfButtons; i++){
followButtons[i].click();
}
setTimeout(nextPage, 500);
}
function nextPage(){
var nextPageBtn = $('.nextPageButtonClass');
nextPageBtn.click();
setTimeout(clickButtons,500);
}
so my question is
1. My for loop to click all the buttons is not working. Is there a better way to click every button class?
2. I need to call the second function after the first one. And when the second one is finished, I need to call the first one again and they must follow each other constantly. I tried setting a timeout and calling the other one ın both functions. But it is not working. How can I do this?
This code basically doesn't do anything. And I have been scratching my head. Sorry I am a huge javascript noob
i am trying to use the confirm method but for some reason the confirm window pops up several times. I googled and tried different things but unfortunately I can't get it running properly. The code is the following:
//user clicks on the delete button
$("#deletePopUpImage").click(function(){
console.log("deletePopUpimageCalled");
//get the id of the image
id = ($(this).parent().prop("id"));
//create the ajax request
data = "typ=function&functionType=deleteUserImage&id="+id;
//open the confirm box
var r = confirm("Are you sure that you want to delete this image?");
if (r == true) {
console.log("loadAjaxCAlled");
//Ajax call
loadAjax(data);
//hide the image and the loader
hideImagePopup();
} else {
//do nothing
}
});
The strange thing is that sometimes the confirm window pops up twice, sometimes three times and sometimes as expected once. That's why inserted the two console.logs.
"deletePopUpimageCalled" always appears just once. However "loadAjaxCAlled" appears several times.
In the success callback of the Ajax request I am just hiding the thumbnail div.
Do you know what's wrong with my code above?
Thanks
Stefan
Probably the code that attaches the event:
$("#deletePopUpImage").click(function(){...});
is invoked several times. Every invocation of .click(...) makes a new handler that fires when the button is clicked.
Some browsers stack up log the same entries into one (so the log doesn't extend so fast), that could be the reason you don't see "deletePopUpimageCalled" many times.
It would the best to check this by debugging it in the browser.
Ok I found the problem. In the Ajax success handler I set the div of the image, that was deleted, to display:none instead of deleting it. Thus divIds could occur twice, three times, etc. After changing the code to delete, it worked smoothly.
I am trying to make a modal object library that will create and open a div, iframe, img, similar to colorbox. I am doing this in pure javascript, so please do not recommend jQuery.
The problem is, when a user creates a new modal using var myModal = new modal(options, width, height), I want it to check if a modal already exists, close it, wait for the close animation, then continue to create the new modal. I can already do everything, but I'm having an issue waiting to create the new modal until the old one is gone. I am aware of webkitTransisionEnd and firing custom events, but that is not the issue. I need the actual code to wait until the old modal is finished closing until it continues on to finish the rest of the function and still return the correct object to the user. Here are some of the things I've tried:
Creating a transisionEnd listener waiting for the animation to end then creating the new modal. (this worked but considering it then becomes a nested function, it's hard to return the correct object).
Using a try, catch block. (this didn't work for my purposes)
Using a countless number of variations of the same thing where I use recursive functions
If anyone has ideas, please feel free to post them. I have tried a lot of things, but apparently not the one thing that I need to. Thanks.
EDIT:
I was able to figure it out. All I had to do was attach a transitionEnd listener to the modal that is already open, then create an additional function outside of the class that would then recall the modal with the same constructor. The code looks a bit like this:
function create(options, width, height) {
return new modal(options, width, height);
}
function modal(options, width, height) {
if (modal != null) {
modal.close();
modal.addEventListener('webkitTransitionEnd', function() {
create(options,width,height);
});
}
return;
}
var animationDuration = 1000;
setTimeout(function(){
// Animation done!
}, animationDuration);
You can't cause code to wait (e.g. pause execution of the current thread of execution) until some future event occurs. Javascript simply does not support that or work that way. It does not have a way to block the current thread of execution other than a couple modal functions like alert().
What you can do is use callbacks to notify some calling code of a future event. But, the calling code will register its callback and be returned to immediately and continue executing so the calling code has to be written to handle the callback implementation.
If you're trying to do all the work inside your library, then it should not be that tough. When the caller creates a new modal, you just have to check for a pre-existing modal dialog. If one is not up you proceed as normal. If one is up, then you register a callback notification with the previous one, store the contents of the constructor, but don't actually create the new modal dialog. Then, when your callback gets called to indicate the previous modal dialog has completed, you finish putting up the new modal.
If these modal dialogs are all of your own creation, then you need to implement completion notification on them so that when they are closed, they can notify any listeners that they're done now. If they use an animation to close and you want to wait for the close notification until the animation is complete, then you can implement that also. If you're using CSS3 animations, then as you appear to already know, you can use the transtionEnd event to know when an animation is done or if you know the timing of the animation and you don't need to be ms precise, you can also just use a setTimeout() to know approx when the animation is complete.
In javascript, if I have an infinite loop:
setInterval("popalert", 5000)
Where popalert() simply pops an alert box, what is the best way to make it such that an alert box does not pop up if there is already a single alert box that has not been closed yet?
There is no way to detect that the alert is there.
Do not use setInterval, use setTimeout.
Reset the timeout after the alert happens.
jsfiddle example
It's impossible to detect the standard javascript alert boxes as they are extremely simple. If you keep spawning them they will just queue and in modern browsers it actually gives you the option to suppress them for a certain page after a few.
I would consider using a different type notification system if having no more than 1 box at any time is important to you. Something like jQuery UI Dialog.
The popalert function could save the state of the alert box.
var bOpen = false;
then when its poped up set it true
and if it closes after pushing ok or something set it false again.
when popalert is called again it checks the bOpen var and if its true, it just doesn't open a new popup.
also I would use settimeout, so you don't get this endless loop stuff blocking your gui.
You can't detect if an alert box is already here.
Your navigator manage this alert box, so they can't popup if another is already here.
You can use a global javascript variable (out of any function) and set this var initially to false. If your popalert function is called, check if the global var is false. If so, pop your alert and set the var to true. Doing this only one alert will be shown, but your function will be executed again and again (if this is important).