How to run a task after the page being killed in browser? - javascript

First of all, it has two pages: example.com/pageA and example.com/pageB, it's not a SPA.
How to run a delay task after the page being killed by history.back?
I tried using setTimeout but failed to execute the task after history.back, because the timer will be clear in stack when page change.
var a = 1
function refresh() {
// <p id="count"></p>
count.innerText = a
}
function foo() {
a += 1
refresh()
}
// called in PageB
function goBackA() {
setTimeout(foo, 1000)
history.back()
}
In PageA the count still be 1 instead of 2.

For security reason, your goal to run some code after page being killed will never be supported by the browser, because it's dangerous when some code can run on a different page.
Once the page being reload/killed, all the unfinished tasks will be clear even if in a SharedWorker.
So, two ways to accomplish your logic:
change to SPA
give another page a hint like query

Related

How i do a simple loop on a event?

I searched everywhere a simple example for loop a event whiteout the processor up to 70%. I don't find the awsner so i need help. I just need to everytime the page refresh it do the code.
Here the code:
page.once('load', async () => {
console.log("Page loaded!")
// Example of code to execute when the page reload
const searchBtn = await login.$x("//button[#id='btnEnter']");
await searchBtn[0].click();
});
You need code which executes everytime the page was loaded. You can achieve that by calling
function onLoadHandler() {
/**code goes here ***/
}
page.on('load', onLoadHandler)
You do not have to loop over this. Your onLoadHandler function will be executed everytime this particular page is reloaded.
What you did is to call page.once('load', onLoadHandler). This listens to the 'load' event once and then the handler removes it selve, it does it "once".
Loop
So probably if you looped the function page.once()(doing it 10000 times a sec) using a while loop or something your processor would ofc reach 70% usage .. Whenever your processor goes crazy like this, your code is suspected to be way to ressource heavy. In general that should not happen when running normal app without handling 10k requests per second or something.
Feel free to leave a comment.

setTimeout firing too soon(?)

Alright, right now I'm writing a little JavaScript code that I can just simply copy paste into the Firefox Console and run. (I'm sorry, I'm still a massive noob, and I want to write a little script that basically, opens a certain web page and collects information form certain divs in it.)
However, I'm struggling at the moment. I would like to open a certain webpage, and then, after it is entirely loaded, execute a certain function. (for simplyfying reasons, this function just counts from 0 to 99.)
function openGroupsPage() {
window.location.replace(groupURL);
setTimeout(function() {
for (i = 0; i < 100; i++) {
console.log(i)
}
} , 10000)
}
openGroupsPage()
My problem is : The incrementing function never gets called (or atleast it seems like it because i can never see any kind of output in the console.) Why is my setTimeout not working or what is another option to accomplish what I would like to do? I would just really like to run a specific function when the newly accessed website is finished loading entirely.
When you change the location, the window object and all of its associated things (including timers) are discarded and a new one created. You can't schedule code to run in the new document from within the old document (not even from the browser console). You'll have to paste and execute your code after navigating to the new page, not before, which means you can't navigate to it from within your code.
You might look at tools like TamperMonkey or GreaseMonkey and such that let you run code in response to pages loading that match certain URLs.
window.location.replace() exits the current page and loads a new one. So any remaining JavaScript of the current page isn't executed anymore
Your function is working fine the only problem is window.localtion line reload the website with the url you provided so the entire page is getting reload from start and your page lost your function.
try the below to understand
function openGroupsPage() {
//window.location.replace('http://www.google.com');
setTimeout(function() {
for (i = 0; i < 100; i++) {
console.log(i)
}
} , 1000)
}
openGroupsPage()
You could add an eventListener do the document of the page which fires when the page is loaded.
document.addEventListener('DOMContentLoaded' function(e) {
// page is loaded do you fancy stuff in here
// no timeout needed
});
EDIT: Overlooked that he want to do it over the console on a random page. This won't work because on locationchange all current scripts are stopped and global objects are destroyed.
Use something like Greasemonkey for that.

HTML/JavaScript: How to run a loop while running other code?

I want to have code that simply will count up by one every second or so. However, I also want to be able to run other code alongside it.
Example:
while(true){
Number + 1 + OtherNumber = Number
}
And also be able to run this at the same time:
function onButtonPress() {
OtherNumber++
}
Note: I do not want to increment otherNumber at an interval, but rather on the press of a button.
You can use setInterval:
var intervalId = setInterval(function() {
OtherNumber++;
}, 1000);
It will increase OtherNumber by one approximately every second.
setInterval returns ID of interval, which can be used to stop it:
clearInterval(intervalId);
Demo snippet:
document.body.innerHTML += "Start<br/>";
setInterval(function() {
document.body.innerHTML += "Interval step<br/>";
}, 1000);
document.body.innerHTML += "Look! Code is completed before interval step<br/>";
If you want to run code as two separate threads you will have to use web Workers as Javascript is single threaded and can not run more than one function at a time.
If you create a function
function workForever(){
while(true){
.. do work
}
}
You will completely block all code, no events will get called, no other javascript will be executed. Most browsers will throw up a dialog reporting that a function is taking a long time do you want to kill the page. But your code is stuck in that loop and can only be exited from within the loop itself.
WebWorkers are a good solution to multitasking in the Javascript environment, but you still need to provide some non execution time to allow the webworkers to communicate. The while(true) will block all communication with the workers, in effect making them useless.
SetInterval, setTimeout, requestAnimationFrame will also be blocked. Javascript unfortunately is single threaded and will never be able to run two functions at the same time.

Wait until angularjs is done before running a function

We're running an angular app and need to wait until angular is done on the page before we try and run our automation.
Our automation is separate from the application, so we need to be able to run a javascript function against the browser to know if the DOM is finished loading and the events are all attached.
jQuery.active is actually tracking the number of active AJAX requests, not the active amount of jquery functions running.
If what you're aiming for is something that fires after all ajax calls are done, do something like this:
var counter = 1;
ajaxCallComplete = function() {
counter++;
if(counter >= ajaxCalls) {
//Do automation
}
};
Have that declared somewhere, and have your ajax call count declared as well. Have each AJAX call invoke this when it finishes. Don't know if this answers your question fully, but it should get you in the right direction.

To execute Flex cleanup function when browser is closed by user

I have a Flex client application. I need a clean up function to run in Flex when the user closes the browser. I found the following solution on the net, but it only works half-way for me. How could I fix it? Thanks in advance for any responses!
Symptoms
CustomEvent triggered, but not executed. >> EventHandler for CustomEvent.SEND_EVENTS is defined by a Mate EventMap. All the handler does is to call an HTTPServiceInvoker. In debug console, I'm able to see the handler and HTTPServiceInvoker being triggered, but neither the resultHandlers nor the faultHandlers were called. I know this event handler has no problem because when I dispatch the same CustomEvent.SEND_EVENTS in a button click handler, it behaves exactly as I expected)
Browser seems to wait for cleanUp function to complete before it closes. (all traces were printed before browser closes down)
Code
I added the following into the index.template.html
window.onbeforeunload = clean_up;
function clean_up()
{
var flex = document.${application} || window.${application};
flex.cleanUp();
}
And used the following in the application MXML file
import flash.external.ExternalInterface;
public function init():void {
ExternalInterface.addCallback("cleanUp",cleanUp);
}
public function cleanUp():void {
var newEvent:CustomEvent = new CustomEvent(CustomEvent.SEND_EVENTS);
newEvent.requestObj = myFormModel;
dispatchEvent(newEvent);
// for testing purposes
// to see whether the browser waits for Flex cleanup to finish before closing down
var i:int;
for (i=0; i<10000; i++){
trace(i);
}
}
My Setup
FlexBuilder 3
Mate MVC Framework (Mate_08_9.swc)
FlashPlayer 10
Unfortunately, there is no solid way of doing such clean up functions that execute asynchronously. The result/fault events of the HTTPService occur asynchronously after the cleanUp method is returned. The browser waits only till the onbeforeunload function (the js clean_up function) returns. Unless you call event.preventDefault() from that function, the page will be closed. Note that calling preventDefault() will result in an ok/cancel popup asking:
Are you sure you want to navigate away from this page?
Press OK to continue, or Cancel to stay on the current page.
If the user selects OK, the browser will be closed nevertheless. You can use the event.returnValue property to add a custom message to the popop.
//tested only in Firefox
window.addEventListener("beforeunload", onUnload, false);
function onUnload(e)
{
e.returnValue = "Some text that you want inserted between " +
"'Are you sure' and 'Press OK' lines";
e.preventDefault();
}
You'll never be able to reliably detect the browser code 100% of the time. If you really need to run actions then the safest course of action is to have clients send "i'm still alive" messages to the server. The server needs to track time by client and when a client doesn't send a message within the specified amount of time (with some wiggle room), then run clean-up activities.
The longer you make the time the better, it depends on how time-critical the clean-up is. If you can get away with waiting 5 minutes that's great, otherwise look at 1 minute or 30 seconds or whatever is required for your app.
An alternate way to clean up the session on client side is to use JavaScript and external.interface class in as3. Here is sample code:
JavaScript:
function cleanUp()
{
var process;
var swfID="customRightClick";
if(navigator.appName.indexOf("Microsoft") != -1){
process = window[swfID];
}else
{
process = document[swfID];
}
process.cleanUp();
}
and in the as3 class where the clean up function is defined use this:
import flash.external.ExternalInterface;
if (ExternalInterface.available)
{
ExternalInterface.addCallback("cleanUp", cleanUp);
}
function cleanUp():void {// your code }

Categories

Resources