javascript: check if PageRequestManager pageLoad already fired - javascript

Let's say there is a function that registers event handler for page load:
function onLoad(pageLoadedHandler) {
Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(pageLoadedHandler)
}
As it turned out, if page is already loaded pageLoadedHandler will not be called. I want onLoad function to call passed event handler if page is already loaded, so how can we check this?
We can go with some ugly way like this:
Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded( function () {
window.pageIsAlreadyLoaded = true;
} );
function onLoad(pageLoadedHandler) {
if(window.pageIsAlreadyLoaded){
pageLoadedHandler();
} else {
Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(pageLoadedHandler);
}
}
It will only require putting this code to the early loaded JS file. But there should be a nice way to do this checking.

Related

JS - Elements still null after body.onload

According to this question, by the time the body onload gets called, all of the objects in the document are in the DOM, and all the images and sub-frames have finished loading.
I have some JS that is supposed to fire at body onload but my attempts to getElementByID are returning null which makes me think it's firing earlier than I think it is.
Am I wrong in my interpretation of body.onload or am I doing something else wrong?
Here is my code:
<script type="text/javascript">
window.document.body.onload = doStuff;
function doStuff() {
var txtElement = document.getElementById("myTextField");
if (txtElement != null) {
alert(txtElement.value);
}
else {
alert("Element not found!"); //This alert is always thrown
}
}
</script>
You are actually calling the doStuff function before the DOM is loaded because you have parenthesis after the function name, which causes the function to be invoked as soon as that line is encountered.
When you register a function as a callback to an event, you just want to reference the function, not invoke it. Also, you only need to register the "page" load function to the window.
Change:
window.document.body.onload = doStuff();
to:
window.onload = doStuff;
Additionally, you should modernize your code and, instead of using an event property of an element (which only allows for one function to be stored as a callback to an event), you should use the addEventListener() method to register callback functions.
Lastly, the type attribute is no longer necessary on script tags.
<script>
window.addEventListener("load", doStuff);
function doStuff() {
var txtElement = document.getElementById("myTextField");
if (txtElement != null) {
alert(txtElement.value);
}
else {
alert("Element not found!"); //This alert is always thrown
}
}
</script>

how to setTimeout within a function before navigating to other tab

I want to set a specific time out before the function navigates to another tab.
somefunc: function() {
PageFrame.goToTab('test', function(item) {
if(!item.search){
return false;
}
//else do some stuff
}, this);
}
The issue is when the PageFrame.goToTab is called to redirect to the "#test" page, the test page hasnt completely loaded then, hence I get a undefined on item.search, though it loads after the error has been thrown. Hence I want to add a timeout for the function to wait until the page loads and then check for this condition: if(!item.search){}
How can I achieve this?
As Jaromand X said you should use an event that will tell you when the page has fully loaded instead just setting a timeout. From MDN Documentation "The onload property of the GlobalEventHandlers mixin is an event handler for the load event of a Window, XMLHttpRequest, element, etc., which fires when the resource has loaded."
That means that once the content of the window has finished loading the onload event will be fired.
To use such event you will have to assing and 'event handler' this is a function that runs whe the event fires.
In your case you should do this:
function somefunc() {
PageFrame.goToTab('test', function(item) {
if(!item.search){
return false;
}
//else do some stuff
}, this);
}
window.onload = somefunc;
So you 'somefunc' will run when onload event fires. You don't write window.onload = somefunc(); because what you assign as event handler is a pointer to your function.
somefunc: function() {
setTimeout(function() {
PageFrame.goToTab('test', function(item) {
if(!item.search){
return false;
}
//else do some stuff
}, this);
}, 5000);
}

How do I call a function once after all chrome.cookies.onChange events fire?

how do I call a function once after all cookies.onChange events fire, I kown
chrome.cookies.onChange.addListener
but it call event handler everytime after every cookies get changed, I want to call event handler only once after all events fired.
How I can do that?
Thank you!
var hasBeenCalled = false;
function doSomethingOnce() {
if (!called) {
console.log("I haven't been called before");
// do fancy stuff.
hasBeenCalled = true;
} else {
// do nothing, function already called.
};
};
chrome.cookies.onChange.addListener(doSomethingOnce);
Or better yet, you can probably find a chrome.cookies.onChange.removeListener(doSomethingOnce);,
in which case inside your doSomethingOnce function, after you do whatever you want to do, you call chrome.cookies.onChange.removeListener(doSomethingOnce);

Run Two Functions (One In External File, One In Inline Javascript) On window.onload

I'm developing a website and I have an external JavaScript file that is linked to every page of the site which executes when the window.onload event is fired. The JavaScript executes fine on all pages which do not contain any inline JavaScript.
Any page that contains inline JavaScript also contains a JavaScript function which executes when the window.onload event is fired.
The problem I'm having is that the external JavaScript does not execute when window.onload is fired, only the internal JavaScript does. It appears as if the inline JavaScript function overwrites the function from the external JavaScript file.
I know that my external JavaScript file is first executed and then the inline JavaScript is executed. Is there anyway that I can execute both functions on window.onload?
How about changing the script that executes second to something like this:
var onload = function () {
// Do something
alert('Hello');
};
if(window.onload) {
// If a function is already bound to the onload event, execute that too.
var fn = window.onload;
window.onload = function () {
fn();
onload();
};
} else {
window.onload = onload;
}
Or use a library like jQuery which lets you do:
$(document).ready(function() {
alert('Hello');
}
This might be more of a work around than a proper fix but could you put your inline JS at the bottom of the html page so it is automatically called after the page is loaded. That will mean you don't have to actually use window.onload()
Two ways :
1 - Use addEventListener.
window.addEventListener("load", function(){ /*code*/ }, false);
2 - Use a hack like this:
var func = window.onload;
window.onload = function() {
if ( func ) func();
/* code */
};

Adding multiple onload handlers

I have two js files, each one with its own window.onload handler. Depending on how I attach the two onload handlers to the window object I get a different behaviour on the second handler.
More specifically, here is my html file:
<html>
<head>
<title>Welcome to our site</title>
<script type="text/javascript" src="script1.js"> </script>
<script type="text/javascript" src="script2.js"> </script>
</head>
<body id="pageBody">
<h2 align="center">
Wellcome to our site... c'mon in!
</h2>
</body>
</html>
It loads two js files, script1.js and script2.js.
Here is the version of these two scripts that leads to the (at least by me) unexpected behaviour.
Script1.js:
window.onload = initAll1(); // attach first onload handler
function initAll1() {
alert("initAll1");
document.getElementById("redirect").onclick = foo; // attach an onclick handler
}
function foo() {
alert("we are in foo");
return false;
}
Script2.js:
addOnloadHandler(initAll2); // with this we should attach a second onload handler
function initAll2() {
alert("initAll2");
if (linkHasOnclickHandler(document.getElementById("redirect"))) {
alert("correct!");
}
else {
alert("wrong!");
}
}
function addOnloadHandler (newFunction) {
var oldevent = window.onload;
if (typeof oldevent == "function") {
window.onload = function() {
if (oldevent) {
oldevent();
}
newFunction();
};
}
else {
window.onload = newFunction;
}
}
function linkHasOnclickHandler() {
var oldevent = document.getElementById("redirect").onclick;
if (typeof oldevent == "function") {
return true;
}
else {
return false;
}
}
In Script2.js I tried to add the second onload handler in a nice noninvasive way using function addOnloadHandler(). This function does not make any assumption on whether there is already any onload handler attached to the window object. It is noninvasive because it should add the new handler without deleting previous ones.
The thing is that when loaded with addOnloadHandler(), initAll2() is not capable of detecting the fact that document.getElementById("redirect") already has foo() attached as an onclick event handler (see initAll1()). The alert message "wrong!" is triggered, which to me seems to be the wrong behaviour.
When I forget about addOnloadHandler() and attach both onload handlers in Script1.js using:
window.onload = function () {initAll1(); initAll2();};
then everything works as expected, and initAll2() launches the "correct!" alert message.
Is there something wrong about addOnloadHandler()? Could anybody make it work? I would really like to use it instead of the second method.
Thanks!
Just in case future people find this, and are looking for a way to use multiple event handlers when the object itself doesn't support addEventListener, attachEvent or some other form of listener stacking - i.e. it is a bespoke object, badly implemented. Then you can do the following:
object.onload = (function(pre){
return function(){
pre && pre.apply(this,arguments);
/// do what you need for your listener here
}
})(object.onload);
Each time you use the above code the previous onload listener is passed in as an argument, and when your new listener is triggered it runs the old listener first - meaning you can stack many listeners like this, if you so wish. However, this will only work for as long as the above code is always used to add listeners to your object. All your hard work will be undone if somewhere else it is overridden with a simple:
object.onload = function(){}
As a note to coders, if you are to implement a library, plugin or constructor, and it is possible other coders will take over your work. Please, please code the ability for multiple event listeners. It's really not that difficult.
You need to look at addEventListener and attachEvent, which are native implementations of your addOnloadHandler.
PPK's reference on addEventListener explains how do this pretty well:
http://www.quirksmode.org/js/events_advanced.html
Thanks for the answers!
I rewrote my script2.js using addEventListener and attachEvent like this:
//addOnloadHandler(initAll1); // it works only when uncommenting this
addOnloadHandler(initAll2);
function initAll2() {
alert("initAll2");
if (linkHasOnclickHandler(document.getElementById("redirect"))) {
alert("correct!");
}
else {
alert("wrong!");
}
}
function addOnloadHandler(newFunction) {
if (window.addEventListener) { // W3C standard
window.addEventListener('load', newFunction, false); // NB **not** 'onload'
}
else if (window.attachEvent) { // Microsoft
window.attachEvent('onload', newFunction);
}
}
function linkHasOnclickHandler(element) {
var oldevent = document.getElementById("redirect").onclick;
if (typeof oldevent == "function") {
return true;
}
else {
return false;
}
}
As you can see, addOnloadHandler() has been rewritten using the native implementations you guys mentioned. I left script1.js untouched.
The resulting code still does not work (i.e., the "wrong!" alert message is shown). It only works when I register the onload initAll1() handler twice by uncommenting the first line of code in script2.js.
Apparently, mixing
window.onload = handler1;
and
window.addEventListener('load', handler2, false);
or
window.attachEvent('onload', handler2);
does not work fine.
Is there any way to work around this problem that does not imply touching script1.js?
Just in case you wonder why I don't want to touch script1.js, the reason is that I want my code (script2.js) to be reusable in other projects as well, no matter which other js files each project uses. So, it should work with every possible event-handling registration method used in script1.js.
thanks once more for your help!

Categories