Stop script in dynamically loaded content - javascript

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.

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

Keep javascript running on different pages

I have a javascript that does some work then goes to another page.
I have it in a couple versions:
One is a bookmarklet, the other is a script for tampermonkey and js code.
Once it's there though I can't find a way to continue having it run.
I know javascript runs on the page but is there a way to have it server sided or something so that when the page is changed to another the script can continue once the page is loaded?
What I want:
I press button,
stuff happens,
I'm redirected to another page,
stuff happens again,
redirected,
stuff happens...
etc.
But I want it to not need any user input rather then the initial starting.
I have the code to the point where it does stuff then redirects but I don't know how to have it continue on the different page.
Make a method of some stuff happening and place this method on common js file that is linked on every page and call that method on every page $(document).ready(fucntion(){}) event.
function anyMethodName(){
//Do your required stuff here.
}
and call it on $(document).ready(fucntion(){}) like:
$(document).ready(fucntion(){ anyMethodName(); })

Altering elements that are loaded from buttons after the page itself is finished loading

I realize the title is a bit unclear, so I'll elaborate as well as possible. Essentially, there is a webpage that the user visits. After the page completes its initial load, the user may then click a button on the page which will load new content into the page. Something like <div class="expanded" style> -- basically a bunch of text and perhaps some links.
I essentially need to alter the contents of this newly loaded area. Right now, I am running something like:
$('div.expand-button').click(function(){ //When the button to load new content is clicked...
And then fire off my document.querySelectorAll function at this point. However, if I do this, the new content is not finished loading when the function runs, and, as a result, nothing happens. What's the best way of delaying my function so that it will only run after the new content area is loaded?
I had a similar problem recently and the simplest solution I found (albeit probably not the best) was to use setTimeOut. So your code would look something like :
$('div.expand-button').click(function(){
YourLoadNewAreaFunction();
setTimeout(function() {
//do stuff you needed the page completely loaded to do
}, 1000);
}
1000 is of course an arbitrary number of milliseconds I chose, you could choose whatever time you deem necessary to completely load your new area. Assuming your new content loads in under a second, the above should work.
From what I've seen online, you could also try looking into callbacks.

How to access the DOM after a previous JQuery call

I'm not too familiar with JQuery so please be patient.
Essentially, I have two hyperlinks on a view that runs some JQuery script:
Delete</td>
.
.
Undo
So, each of these links access different parts of the same .js file. My "Delete" does some processing which does a soft delete in the database. The DOM loads and this works fine. I'm using firebug and, when I insert a console.log in .js I can see the id of the Customer I want to delete and the rest is straight forward.
$(container).find('a.deleteCustomer:first').click(function(e) {
console.log("CustomerId " + $(container).find('input[name=Customer_CustomerId]:first').val());
My "Undo", however, accesses the same .js on a different line and console.log in the 'undo' part of .js reveals that it's not being hit.
$(container).find('a.undoCustomer').click(function(e) {
console.log("CustomerId " + $(container).find('input[name=Customer_CustomerId]:first').val());
So, it appears that the DOM is not ready (?). If this is the case, how do I fix this? Do I have to reload the DOM manually? If so, how?
P.S. When I click 'Undo' first nothing seems to happen i.e. I don't get any console.logs in FireBug. However, if I refresh the browser, it runs as expected i.e. the undo jquery about executes.
Without the full code, it is difficult to tell. From your post, title and comments, I see two possible causes.
First, you might be running your code before the DOM is fully ready, then try to wrap all your javascript initialization script in:
$(function() {
... // your code here
});
Second, are you deleting the "input" when you click on delete? If this is the case, it would be normal that "find" does not recover it. The solution to have an undo in such case would be to hide the "input" and show it back when clicking "undo".

Running jQuery code retrieved from ajax request, what should I remember to delete?

I understand that it's possible (and I have done it) to return javascript and jQuery code (which of course is javascript... hehe) when doing a jQuery ajax request and running it once it reaches the browser.
What I'm wondering is if I return data, let's say a form, that I present in a dialogcontainer. What should I delete myself once that container is closed by the user and what does jQuery understand by itself to delete.
My idea is to build a page that require very little page reloads and once a user clicks on a button I present them with a form or some other content fetched from the server. Alongside that content the javascript required by that content should also be retrieved. But if the dialog is closet I don't want tons of javascript to be left eating memory. Any way around that?
You could unbind the click event that does the ajax call. If nothing is going to change if they open the dialog again, then this should be fine. While you unbind it you could then change it more a toggle type of thing (Show/Hide), since the javascript and HTML should already be set now.
But it really depends on what you are trying to do. The ajax call will only happen once they click it. It's not going to continually refresh unless you want to. So there should be nothing in the background running except for binding events like click, which is ok.

Categories