setTimeout not executing the passed function - javascript

I'm working on a simple interface for testers to use, which I'm writing as an HTML page. What I need to do is open a specific URL when the user presses a button (the URL triggers a Hudson/Jenkins job on another server). Here is the code I'm using to accomplish this:
function triggerJob() {
var url = "...";
var trigger = window.open(url);
setTimeout(function() {trigger.close();}, 1000);
}
A couple of notes:
I know this a bad way of accomplishing what I want to do. I have already implemented the solution using jQuery, and for some reason the job on the Hudson server does not get kicked off when querying the URL in that way. The weird thing is that when I query it using a Ruby script from the same machine, it works just fine.
I have to do the timeout because if I just open the window then immediately close it, the browser does what it is supposed to, but it's too quick for the Hudson server to register it and start the job.
I have tried putting other statements besides trigger.close(); inside the anonymous function, and they are not executed either. There is no question that setTimeout is not executing the block it is supposed to be.
Thank you for any help you may be able to give me. I have been toying with this for hours and cannot figure out why my code is not doing the timeout right.

figured out this problem in the course of doing something else, so I thought I'd share the solution in case anyone else has the same problem. The issue was that I was calling this function using the onClick attribute of a submit button in a form. When the form is submitted it calls the function, and then the page is immediately reloaded after the function executes, which cancels the timeout that was set in the triggerJob function. You must use a link, radio button, etc. if you want to use setTimeout in this manner. Thanks for everyone who tried to help me.
Drew

Related

Clicking a dialog before page loads in protractor

Currently I am attempting to click a dialog box that appears before a page loads. I am using the browser.get(extentionHere) function to load the page in a manner resembling this:
it(..., function(){
browser.get('#/frontPage);
element(dialogIdentifier).click();
When the page loads Protractor does nothing until a timeout, an investigation into this behavior led me to find that it was the result of the page hanging as the rest of the page 'waited' for the dialog to be clicked. In essence the URL was meaningless as Protractor thinks the page has not loaded and treats the dialog as more of a browser feature (it is not) instead of the webpage. Hence, the element(...).click() did not execute, and of course, the program could not continue.
In attempting to find a solution I found the function browser.executeAsyncScript which I thought might allow me to execute multiple functions in an order. My, albeit ignorant, attempt led me to this:
browser.executeAsyncScript('browser.get("#/frontPage")').then(function () {
element(dialogIdentifier)).click();
});
which, as implied by my asking this question, did not work (giving me some sort of "browser is not a function" error), if I am even using this function correctly for the correct purpose it would seem to fit the bill; allowing me to click the dialog.
Any help would be appreciated (and I am not limiting answers to any function. So please, let me know what ideas you have).
Thanks in advance.
I'm assuming that angular isn't loading since the dialog pops up before the page loads. The below code tells protractor not to wait for angular to synchronize and then resume synchronization after the dialog box is clicked.
browser.ignoreSynchronization = true;
browser.get("http://www.google.ca").then(function () {
element(dialogIdentifier).click();
});
browser.ignoreSynchronization = false;

How can I navigate to a different href first, then let the code continue, using just JavaScript?

When I enter this code into the console on Chrome browser, the alert comes first, followed by the new href, even though the 'window.location.replace()' is in-front of the alert:
window.location.replace('http://stackoverflow.com/');
alert('hi');
I would like to know how to navigate to the new page, and then let the alert happen. How would I do that?
I would like to know how to navigate to the new page, and then let the alert happen. How would i do that?
You can't. The JavaScript environment in browsers is tied to the page. When the page is torn down, the environment is torn down with it. Even if you were to do something like this:
// Example of something that DOESN'T work
window.location.replace('http://stackoverflow.com/');
setTimeout(function() {
alert('hi');
}, 100);
...the timer callback would never fire, because the environment is torn down before it has a chance to.
All you can do is pass information to the next page so that code on that next page runs.
I think #T.J Crowder's answer covers it up very well, but I just wanted to emphasize his last sentence
All you can do is pass information to the next page so that code on
that next page runs.
That would of course only be implying you are redirecting the user to a location you own (unless you own Stack Overflow and I wasn't aware...), and a solution would be to pass GET parameters for example to alert the message you want, like this
window.location.replace('http://stackoverflow.com/?msg=hi');
Then in the other page, you would get the parameter msg and simply do
alert(get_msg);
The message can of course be passed via other way than GET (POST for example), and it is how most "known" frameworks work with their "flash" messages (which is no more JavaScript related)

Wait until all scripts are finished before enabling a button

I've found variants of this problem on Stack Overflow but nothing my matches my specific circumstance. Hopefully someone has some insight.
Right now I'm working on a web application where there is a button (technically an anchor tag) that spawns a list of items when pressed. The issue is, if the user presses this button rapidly twice in a row, the list will be spawned twice-- the button is meant to clear the list before spawning it to prevent duplication, but something about the way the scripts interact is causing this bug. The button spawns the list by making an ajax call to a server.
Now, I've tried fixing this bug by flipping a boolean value to 1 when the button is pressed, and making the button do nothing until it is 0 again. This seems not to work regardless of where in the code I set the value to 0 again: I've tried putting it at the end of the ajaxGet function, as well as after page load, but neither solution works.
Ideally, I would like a way for the button to become enabled as soon as the page is completely finished loading and rendering. Ultimately, what's needed is a way of preventing the user from pressing the button twice in a row. I've considered using a timer for this, but I'd prefer not to have to resort to that.
Any ideas? Let me know if you would like code snippets.
===========================================
EDIT: Thanks everyone for your answers! I used a variant of Fibrewire's answer to solve the problem, and it works great. At the beginning of the method that the button calls, I put the following code:
if (actionsDisabled == 1) {
return;
}//if
else {
actionsDisabled = 1;
setTimeout("actionsDisabled=0;", 1000);
}//else
Where actionsDisabled is a global boolean. It might not be as airtight as it could be (in particular, you'd hit a problem if the list took more than a second to load), but it's elegant and functional, and has the added bonus of reducing server requests (if traffic ever became a problem, you could restrict calls to once every 5 or 10 seconds or whatever). Thanks again!
you can disable the button after the first click
Disabling the button after once click
and if you need the user to be able to click the button again in the future you can use the setTimeout() method to re enable it after a brief pause
http://www.w3schools.com/jsref/met_win_settimeout.asp

Calling a greasemonkey function on a user clicking a button

I have written a script that adds an additional column and a link in each row. The problem is I wan the links to call a function in my greasemonkey script and pass a variable to it.
I have read that due to the nature of greasemonkey being in a sandbox its not possible without a function called 'unsafeWindow'. I can't for the life of me figure out how and a lot of the information seems to be out of date.
Please someone put me out of my misery :)
The exact approach depends on details that are not in the question. You might need to post the code and exactly what variable you want passed.
But, in general, you could do something like this:
NewlyAddedLink.addEventListener ("click", function() {YourFunc (SomeGlobalVariable);}, false);
You don't necessarily have to worry about unsafeWindow.

Catching the specific Javascript code being executed onClick

I am working on a site that has loads of legacy Javascript and jQuery includes and there is no documentation to show what is happening when.
I have a specific problem to fix and I cannot find the relevant code that is being executed when a button is clicked. To save me from trawling through (and making sense of) hundreds of lines of legacy script, is there a feature, possibly in Firebug, that will identify what script is being executed when I click on a button?
I believe there is a feature in Firebug's console window called Profile. Click profile, click the button, then click profile again. It should give you what all functions were called in that time. Be warned that if this code includes jQuery, you might get a huge long list of functions because jQuery uses tons in its code. Unfortunately, the profiler will also show anonymous functions, which can really be a pain.
Otherwise, do a search in the code for the button's class or ID and go through them. If you have an id of fancy then you might do a search for #fancy in your code and attempt to find it. That may lead you in a general direction, at least.
You can click Firebug's "Break on next" button (in the Script tab; it looks like a pause button), then push the button that you want to debug.
The next time any JavaScript code executes, Firebug will break into the debugger and show you that line of code.
The break button didn't work for me. Instead I did edit the onclick attribute with FireBug and prepended it with "debugger;" ... then you'll break right there once you click :)
None of the above answers worked for me. I am trying to use Firebug to figure out how a feature on a page is working for a site I have no control over. Here is what worked for me.
First, got the id of the element I am clicking on from the page source, and then get a temporary reference to it by creating a watch (under the script tab):
tmp=document.getElementById("idOfElement")
Next, I assigned the current onclick value to another temporary variable.
oldfunc=tmp.onclick
Next, I defined a new onclick function. Initially I tried putting debugger; as the first thing in the function, but this does not work! So instead, I created an alert:
tmp.onclick = function() { alert("Ok"); oldfunc() }
Now, as soon as I click on the button the alert comes up, at which point I then click the "Break on next" button as outlined in another answer to this question. Then I dismiss the alert and immediately I am in the debugger at the correct place.
In my case, the "Break on next" button did not work by itself, because there are a lot of other events, just mousing over the page was causing the breakpoint to be hit, preventing me from ever clicking the button.
In Firebug you can set a breakpoint in some JS and then you get a stack which will let you know the current function call stack. So if you set the breakpoint in function used by several handlers then you can use this to discover exactly which handler you are in.
This probably won't work if you are dealing with AJAX callbacks and the like though.

Categories

Resources