Javascript, pause/resume window.load event - javascript

I have an unusual problem that is beyond my client side skill set. I have an html page with two consecutive script tags in the body. Both script tags fire an ajax request to retrieve content and then put it in the DOM. I control the first script tag, and I don't have any control or knowledge about the second script tag. I just know it makes an ajax call and put stuff in the DOM. I also know that my tag is first.
I want my script tag to fire immediately and pause/stop the second tag. Then, contingent on what my ajax returns, I may choose to execute the second script tag. How do I do this?
I wrote a fiddle demonstrating my problem. I substituted settimeout's for ajax calls and Math.random for my decision. Note that the settimeout duration for the first one (my one) is very long, 3 seconds, and the duration for the second one (the one I don't control is very short, .5 seconds. What's happening now is that they are both running immediately. The second message comes in at .5 seconds, and the message from the first comes in at 3 seconds 50% of the time.
I want the first script to run, wait 3 seconds, make a decision and either print the first message immediately, or call the second script which would wait an additional .5 seconds to print the second message. I should never see both messages at the same time, and I should never see the second message before 3.5 seconds.
Again, I don't know any knowledge over the contents of script two. You could easily hide id=ext_div in this case, but I don't know what that id is. That is not the answer I want. I was thinking about grabbing the event on the first script and doing something to that, stopPropagation or something like that at the TODO1 comment. But that doesn't work. Event if it did, I would need a resumePropgation function which I don't event think exists.

I want my script tag to fire immediately and pause/stop the second tag. Then, contingent on what my ajax returns, I may choose to execute the second script tag. How do I do this?
The only way to make that happen is to make your ajax call synchronous, e.g., pass false as the third argument to XMLHttpRequest#open (or whatever the equivalent is in the library you're using, if you're using one). There are several reasons why this is a bad idea, but if you absolutely, positively need your ajax call to complete before the next script tag is executed, that's the only way to do it. Of course, it means that any DOM elements defined below your script tag in the HTML document won't exist yet.

It feels like you want some sort of dependency management system for your front-end scripts.
Try out RequireJS. You could load in your script, run your ajax request, and depending on your logic, decide whether or not to load the second external script.
This is assuming you can control the markup on the page of course.

Related

Continuing a javascript after using .click() on a button which adds new DOM elements

I am a lowly operations employee without authorization to change the programs and permissions on my machine, and I would like to automate some highly repetitive data entry. I know there are a lot of programs that can do that, however, for the sake of this discussion we'll assume that I'm not allowed to have any of them and I can only script through the debug F12 menu in Chrome. I also probably don't understand half of these words as well as I should.
I have to run test cases on a third-party vendor's highly dynamic website, and I've already successfully written javascript which adds texts to elements in the DOM and presses the "next" button.
The problem is, upon .click()ing the "next" button, it takes time for the page to update, and the update creates new elements which weren't in the DOM when the script was initialized. I need to find a way to delay the execution of the script until the DOM contains all the elements I need to update.
As a really, really crude proof of concept I wrote the pre-filler for each page as a function, and I serially called each function at the end of the previous function, using setTimeout(nextfunct, 10000) to let the page update before executing the next line. (I was going to refine that by trying to create some kind of object listener instead of an arbitrary 10 second delay, but I wasn't even able to get that far.) This approach creates two errors.
1) The script seems to be checking whether the elements are on the DOM before the end of the setTimeout(), so it still gives me an error. If nextfunct is defined as
document.getElementById("doesntexistyet").value = "Fill Me";
console.log("nextfunct ran");
I will get the error message stating there is no element with the id "doesntexistyet" immediately, not after a delay of 10 seconds. The element on the next page will not update.
2) The DOM updating interrupts my script. In the above code, the console output will not ever appear in my console. If I comment out the missing element, so the function only prints a comment, it will still not appear in my console. However, if I comment out the code and I switch the setTimeout to 1ms, "nextfunct ran" will appear in my console, until the page updates, at which time the console will be deleted.
Are there ways around this which I can implement using only vanilla JS and a browser? I'm sure there's a keyword I can search for where someone has discussed this before, but it seems like the vast majority of JS autofilling discussions are oriented towards people designing code to be integrated into a website,
Thanks

Stop script in dynamically loaded content

at the moment I am working on replacing pop-up on a website I inherited. Those pop-ups used modal dialogs, which are on their way out and even were dropped by pop-up blockers on client side.
My approach was loading the HTML of the pop-up into an div on the main site, while hiding the original content, then emptying the div and switch the main content back to visible.
This works so fa, but the loaded content has scripts that run to check if someone is already using that function. The first time you use that function all is fine. The script runs, sees noone is using the function, I go through the stuff, empty the div and return to the main content. When trying to use the function a second time the script to still run (console shows the requests), even though I emptied the div, prompting the eternal "please wait till other user is finished" lines, since the first script is still checking for use, signalling the second script "I'm buisy".
So right now, I am looking for a way to stop the first script, since removing the HTML-content doesn't suffice it seems.
The code so far:
$("#dialog").load("stuffToLoad.htm",function(response, status)
{
if(status=="success"){
$(".fullTable").toggle();
$("#dialog").toggle();
};
})
to get the content. The in-use-check is done with a post-request, that is repeated by a window.setTimeout every second. That part seems to still run.
When everything is done, or the user runs into an error I tried:
function returnToProcVal()
{
$("#dialog").html("");
$("#dialog").toggle();
$(".fullTable").toggle();
}
to delete the function content and scripts, to stop them running. While the DOM says all is gone I can see the post requests being repeated in the console.
I'd be grateful for any pointer or perhaps even better methods to get the function running and returning the user, without the use of pop-ups.

Selenium Webdriver clicks element before Javascript has loaded

I am writing some automated tests in Selenium 2.0 using the Firefox driver. The site uses many bindings, for example an 'input' tag with a 'data-val-method-to-execute' attribute which triggers a javascript function.
Some 10% of my tests fail randomly because the driver clicks an element before the corresponding javascript function got loaded - so nothing will happen.
One solution could be Thread.Sleep - problems are: I would have to implement in all of my tests(quite a lot). They will slow my tests drastically, and time is an issue. A simple dropdown with a sleep of 1 second doesn't always work (so I would have to increase the timeout)
You need to figure out a way to make Selenium wait until the page is ready. There is no "one size fits all" solution for this. It really depends on what you do.
For some complex AJAX/JavaScript, I had to use phantomjs and add code which counts the number of open/active network connections. The test would wait until the number changes (so I know the AJAX request has been sent) and then until the number of active connections drops back to 0 (so I know the AJAX is completed).
Alternatively, try to add a hidden DIV to the page which tells the test "all scripts have finished". Wait for the DIV to appear. The problem here is to make sure that your AJAX handlers create the DIV.
In order to avoid polluting your code, use an empty function which creates the DIV and insert an additional <script> element in the head when running the tests which overwrites the function.

What is the opposite of javascript window.stop()

Once I've executed window.stop(), how can I resume default actions?
I need to make toggle/switch function, that once fired will run window.stop(), and with second run will recover window actions disabled by window.stop().
I misunderstood before how window.stop() works.
I was wrong, there are no any "direct inbuilt" javascript method to reload ONLY THESE ELEMENTS stopped by window.stop(), so by this meaning it's impossible.
However, if it's needed, we can:
loop through each element on the site by our own function
cut website in sections, and load them one by one with ajax, so we will have to reload only specific sections
--but I think either one of these it's too complex to implement to be worthy
So, to "pause website for moment" window.stop() it's not good choice.

Detect when HTML has finished loading AND rendering on the page

Is it possible to detect when HTML has finished loading AND rendering on the page? If so, how?
The page consists of HTML, calls to ajax, receives data back from ajax calls, lots of javascript stuff and some images too. I would like to detect when everything has finished. What I can't do is stick a function call at the end, because I don't know when the end is.
For example, the page has lots of ajax style elements which users can pick and choose from, i.e. user 1 might have a different number of elements than user 2 and even in a different order.
So what I can't do is use the last function to simulate the end of HTML rendering, because I won't know which function will be the last function.
The problem with answering your question is in the last few sentences where you say that you don't know where the end is because of user choices. There are two automatic events you can bind JavaScript to. What jQuery calls $(document).ready() which means the DOM is ready for manipulation (before images load and after external scripts and CSS are loaded) and what is more commonly called body onload (in jQuery this can be written as $(window).load()) which runs after all static assets are fetched. Your Ajax calls will all fire after at least the DOM is ready and there is no defined event for what happens after all of them. For that you need to keep track of them on your own. You could use a "last horse out of the barn" approach. Add a small bit of logic to the end of your Ajax calls to see if it is the last and raise a custom event called "reallyAllDone"
Yes onload
<body onload="load()">
That would detect when the contents of the body have loaded.
$(document).ready
will help you to know when the dom has finished its event and its ready

Categories