Multiple javascript window.onload solution - javascript

Before i ask this question, i never post about questions like this but I don't understand how to implement it in my code. i have code like this
window.onload = function() {
var url = getQueryVariable("url");
document.getElementById('view').src = url;
}
window.onload = function() {
var linkDirect = document.getElementsByClassName("frame");
for (var i = 0; i < linkDirect.length; i++) {
linkDirect[i].href = "http://namablog.blogspot.com/p/demo.html?url=" + linkDirect[i].href
}
}
then, how can I make the code execution using only one window.onload

You can use addEventListener or any jQuery equivalent.
window.addEventListener('load', function (){
alert('Function #1');
});
window.addEventListener('load', function (){
alert('Function #2');
});
Be sure to call these before the window is loaded.

window.addEventListener will not work in IE so use window.attachEvent
You can do something like this
function fun1(){
// do something
}
function fun2(){
// do something
}
var addFunctionOnWindowLoad = function(callback){
if(window.addEventListener){
window.addEventListener('load',callback,false);
}else{
window.attachEvent('onload',callback);
}
}
addFunctionOnWindowLoad(fun1);
addFunctionOnWindowLoad(fun2);

Just my 2 cents, My personal fav way of doing this is as follows:
function window_onload(cb) {
try {
if (typeof cb == 'function') {
if (document.readyState == 'complete') cb();
else if (window.hasOwnProperty('jQuery')) jQuery(window).on('load', cb);
else if (window['addEventListener']) document.addEventListener('load', cb, false);
else if (window['attachEvent']) {
// iFrame
if (window['frameElement']) document.attachEvent('onreadystatechange', function(){ if (document.readyState === 'complete') window_onload(cb); });
else window.attachEvent('onload', cb);
}
else {
var fn = window.onload; // very old browser, copy old onload
window.onload = function() { fn && fn(); ready(); };
}
}
}
catch (err) { if (window['console'] && console['error']) console.error("ERROR[window_onload()]", err); }
return window;
}
This pretty much covers just about everything. What little (mainly extremely old browsers I suppose?) it doesn't cover, you could easily debug, if needed. This also goes ahead and launches the callback if the document is already 'loaded'.

The simplest solution that has worked for me:
function doOnLoad() {
onloadfn1();
onloadfn2();
onloadfn3();
}
window.onload = doOnLoad;
This article has explained it in details: http://developer.expressionz.in/blogs/2009/03/07/calling-multiple-windows-onload-functions-in-javascript/
I hope this helps some of you.

Related

can you guys help me with the order for the dom?

I have a problem with undefined property
I added the first part of my js I have a document.readystate witch suppose to help with the Dom not reading fills but I still get undefined
if (document.readyState == `loading`) {
document.addEventListener(`DOMContentLoaded`, ready);
} else {
ready
}
function ready() {
var hiddentwo = document.getElementById(`sectiontop`)
var hidden = document.getElementById(`sectionone`)
var hiddentwo = document.getElementById(`sectiontop`)
console.log(hiddentwo)
const openModal = function() {
hidden.classList.remove(`hidesection`);
};
const closeModal = function() {
hidden.classList.add('hidden');
};
const closeModal1 = function() {
hiddentwo.classlist.remove(`hidesection1`)
};
const closeModal11 = function() {
hiddentwo.classlist.add(`hidesection1`)
};
window.onload = function() {
hiddentwo.classlist.remove('hidesection1')
};
};
.hidesection1 {
display: none;
}
<section id="sectiontop" class="hidesection1">
Remove this block in your code:
if (document.readyState == `loading`)
{document.addEventListener(`DOMContentLoaded`,ready);}
else{ready}
and replace it with either
document.addEventListener(`DOMContentLoaded`, ready);
or use the ready state change event (which requires checking the state inside your ready function):
document.addEventListener(`readystatechange`, ready);
// and in ready():
function ready() {
if (document.readyState === 'interactive') {
// your code from ready function body here
}
};
You always use either method, never both.
as #Sebastian Simon and # conexo pointed out hiddentwo.classlist.remove must be hiddentwo.classList.remove. Case matters in Javascript.

custom when statement not firing functions

I am trying to make a when statement but it is not working as planned. Basically its a function to call another function when try. First before I explain further here is the syntax
when(function() {
//code here
});
Now basically... Think this way.. We have a progressbar.. We also have a custom event such as...
var pBarEvent = document.createEvent('Event');
pBarEvent.initEvent('pbardone', true, true);
document.addEventListener('pbardone', function() {
//code here
});
//if progress bar reaches 100 dispatchEvent
if (document.querySelector(".progress-bar").style.width === 100 + "%")
{
document.dispatchEvent(pBarEvent);
}
Now that piece of code is an example. If the document loads and its for instance at 50% it wont trigger until you add another event such as keydown or click. I dont want to do that I want to do.... "when" progress bar width equals 100% trigger it. Thats basically what needs to happen. So here is the code for the when statement so far (keep in mind its not the best looking one. As I dont normally do this but I wanted to keep this dynamic and who knows someone who later wants to do this can look at this question)
when function
function when(func)
{
var nowActive = false;
if (!typeof func === 'undefined')
{
func = new Function();
}
if (func)
{
nowActive = true;
clearInterval(whenStatementTimer);
}
else
{
nowActive = false;
var whenStatementTimer = setInterval(function() {
switch(func)
{
case true:
{
nowActive = true;
when();
break;
}
case false:
{
nowActive = false;
when();
break;
}
}
}, 1000);
}
if (nowActive === true)
{
func();
}
}
Now this does not work when I go to try something like....
when(function() {
SmartLeadJS.SmartLeadEvents.customEvents.progressBarFull(function() {
alert("100%");
SmartLeadJS.SmartLeadAds.LeadView.ChromeExtension.General.DynamicStyles.$.style("body", "background", "black");
});
});
It does not trigger. I need help possibly getting this when statement to work. What am I doing wrong? What can I do to fix it? No errors get thrown but it never fires.
edit based on answer
Function tried
function when(currentValue)
{
try
{
var o = {};
o.currentValue = currentValue;
o.do = function(func)
{
if (!typeof func === 'undefined')
{
func = new Function();
}
if (this.currentValue)
{
func();
}
else
{
setTimeout(this.do(func), 100);
}
};
return o;
}
catch(e)
{
console.log(e);
}
}
used as
when(true).do(function() {
SmartLeadJS.SmartLeadEvents.customEvents.progressBarFull(function() {
alert("This divs going through changes!!");
SmartLeadJS.SmartLeadAds.LeadView.ChromeExtension.General.DynamicStyles.$.style(".div", "background", "black");
});
});
This does not work. It never fires. But if I use a onclick listener as such it fires
document.addEventListener("click", function() {
SmartLeadJS.SmartLeadEvents.customEvents.progressBarFull(function() {
alert("This divs going through changes!!");
SmartLeadJS.SmartLeadAds.LeadView.ChromeExtension.General.DynamicStyles.$.style(".div", "background", "black");
});
}, false);
function when(statement){
o={};
o.statement=statement;
o.do=function(func){
awhen(this.statement,func);
};
return o;
}
function awhen(statement,func){
if(eval(statement)){
func();
}else{
window.setTimeout(function(){awhen(statement,func);},100);
}
}
Use:
when("true").do(function(){});
It works now :) . Its important to put the condition in ""!

JS set style for size function

My JS function "set style for size" will not call the bodysmall CSS style sheet no mater how small I make the screen width (screen.width <=480).
However the function will call the bodysmall CSS style sheet if I reverse the function.
(screen.width >=480)
Which proves to me the JS function is working. I suspect there is something wrong with my event handler.
I am not familiar with JavaScript yet so any help would be greatly appreciated.
this is my code below.
<script type="text/javascript">
function setStyleForSize() {
if (screen.width <= 481) {
document.body.className = "bodySmall";
}
else {
document.body.className = "bodyNormal";
}
}
function addEventHandler(oNode, evt, oFunc) {
if (typeof(window.event) != "undefined")
oNode.attachEvent("on"+evt, oFunc);
else
oNode.addEventListener(evt, oFunc, true);
}
addEventHandler(window, "load", function() { setStyleForSize(); } );
addEventHandler(window, "resize", function() { setStyleForSize(); } );
</script>
Try this one instead of yours:
function addEventHandler(oNode, evt, oFunc) {
if ( document.addEventListener ) {
oNode.addEventListener(evt, oFunc, false);
return oFunc;
} else if ( document.attachEvent ) {
var bound = function() {
return fn.apply(oNode, arguments);
};
oNode.attachEvent("on" + evt, bound);
return bound;
}
}
NOTE: You can't specify which event handler has to be used with typeof(window.event), so your if statement is incorrect
See the DEMO
screen.width is never changes, use window.innerWidth instead:
function setStyleForSize() {
if (window.innerWidth <= 481) {
document.body.className = "bodySmall";
}
else {
document.body.className = "bodyNormal";
}
}

passing arguments to a function in javascript but function not working

I have some javascript code which detects whether the useragent is an android, iphone or ipod and then only loads my javascript files if this is the case.
The following code works perfectly but I am aware that I do not need to have two 'createscript' functions (with different names) that do the same thing so I am trying to use a parameter/variable instead. I've tried everything i can think of but it's not working.
<script type="text/javascript">
if(navigator.userAgent.match(/Android/i) ||
navigator.userAgent.match(/webOS/i) ||
navigator.userAgent.match(/iPhone/i) ||
navigator.userAgent.match(/iPod/i)) {
function addLoadEvent(func) {
var oldonload = window.onload;
if (typeof window.onload != 'function') {
window.onload = func;
} else {
window.onload = function() {
if (oldonload) {
oldonload();
}
func();
}
}
}
function createScript()
{
var oNode=document.createElement("script");
document.getElementsByTagName("body")[0].appendChild(oNode);
oNode.setAttribute("id", "newScript", 0);
oNode.setAttribute("type", "text/javascript", 0);
oNode.setAttribute("src", "nav.js", 0);
}
function createScript_()
{
var oNode=document.createElement("script");
document.getElementsByTagName("body")[0].appendChild(oNode);
oNode.setAttribute("id", "newScript", 0);
oNode.setAttribute("type", "text/javascript", 0);
oNode.setAttribute("src", "https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js", 0);
}
addLoadEvent(createScript);
addLoadEvent(createScript_);
}
</script>
And here is the new code with parameters that I have been trying out (its the same as above accept I've set a parameter for the createscript function) But it doesnt work:
<script type="text/javascript">
if(navigator.userAgent.match(/Android/i) ||
navigator.userAgent.match(/webOS/i) ||
navigator.userAgent.match(/iPhone/i) ||
navigator.userAgent.match(/iPod/i)) {
alert("This is a mobile device");
function addLoadEvent(func) {
var oldonload = window.onload;
if (typeof window.onload != 'function') {
window.onload = func;
} else {
window.onload = function() {
if (oldonload) {
oldonload();
}
func();
}
}
}
function createScript(scriptname)
{
var oNode=document.createElement("script");
document.getElementsByTagName("body")[0].appendChild(oNode);
oNode.setAttribute("id", "newScript", 0);
oNode.setAttribute("type", "text/javascript", 0);
oNode.setAttribute("src", + scriptname + , 0);
}
createscriptlibrary = createScript("https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js");
createmyscript = createScript("nav.js");
addLoadEvent(createscriptlibrary);
addLoadEvent(createmyscript);
}
</script>
It's probably something small but I can't figure it out. Thanks for your help.
Edit:
Thanks to #t-j-crowder I have edited my code as follows and this works perfect:
<script type="text/javascript">
if(navigator.userAgent.match(/Android/i) ||
navigator.userAgent.match(/webOS/i) ||
navigator.userAgent.match(/iPhone/i) ||
navigator.userAgent.match(/iPod/i)) {
function addLoadEvent(func) {
var oldonload = window.onload;
if (typeof window.onload != 'function') {
window.onload = func;
} else {
window.onload = function() {
if (oldonload) {
oldonload();
}
func();
}
}
}
function createscript(scriptName) {
var oNode = document.createElement('script');
oNode.src = scriptName;
document.body.appendChild(oNode);
}
addLoadEvent(createscript.bind(undefined, "https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"));
addLoadEvent(createscript.bind(undefined, "nav.js"));
}
</script>
There are still some issues with this code as #t-j-crowder pointed out about the fact that I cannot rely on my two .js files loading in the right order so I will try out the guard as he suggested below in his answer. Thanks for all the comments.
New edit to question-loading in a css file:
I now have the following code which loads my jquery lib and nav2.js file when the page is loaded. This works perfect. I am trying to get my code to load a css file dynamically when the browser supports javascript but it is not working. Can anybody see why? is it because the page is displaying before the css file is loaded? Here is my script code:
<script type="text/javascript">
function loadcssfile(filename){
var fileref=document.createElement("link");
fileref.href = filename;
document.getElementsByTagName("head")[0].appendChild(fileref);
}
function addLoadEvent(func) {
var oldonload = window.onload;
if (typeof window.onload != 'function') {
window.onload = func;
} else {
window.onload = function() {
if (oldonload) {
oldonload();
}
func();
}
}
}
function createscript(scriptName) {
var oNode = document.createElement('script');
oNode.src = scriptName;
document.body.appendChild(oNode);
}
addLoadEvent(createscript.bind(undefined, "https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"));
addLoadEvent(createscript.bind(undefined, "nav2.js"));
loadcssfile("jqueryjava.css");
</script>
The reason that doesn't work is that createScript doesn't return a function, but you're expecting it to.
The simplest way is just to do this:
addLoadEvent(function() { createscript("https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"); });
addLoadEvent(function() { createScript("nav.js"); });
Note, though, that you're giving the same id value to each script tag created by createScript, which isn't valid.
In an ES5-enabled environment, you could use Function#bind, but something about your question suggests to me you can't rely on being in an ES5-enabled environment. But for completeness:
addLoadEvent(createscript.bind(undefined, "https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"));
addLoadEvent(createScript.bind(undefined, "nav.js"));
Actually, no, the simplest way is to use any of several libraries designed for this, like RequireJS. :-)
Side note: Your createScript function can be markedly simpler (and in fact, the one you've quoted in your question has a syntax error as of the + before scriptName):
function createScript(scriptName) {
var oNode = document.createElement('script');
oNode.src = scriptName;
document.body.appendChild(oNode);
}
There's no need to set type, and you don't want to set id unless you're also passing in an id for each script. And both src and type are reflected properties, no need to use setAttribute on them.
And a final side note: Your nav.js cannot rely on jQuery already being loaded if you load the scripts this way. nav.js can be retrieved and evaluated (run) before jQuery is, even though you're creating the jQuery script element first. Scripts added dynamically are not necessarily evaluated in order. So you need a guard on your nav.js code, like:
(function() {
check();
function check() {
if (typeof jQuery === "undefined") {
setTimeout(check, 50);
}
else {
init();
}
}
function init() {
}
})();
That will check for jQuery and wait 50ms if it doesn't find it (and keep doing that forever, you might want a master timeout).
In my latest edit above I was wondering how to add a css file dynamically.
I have used the following code instead and it is now working. Thanks
<script type="text/javascript">
var headID = document.getElementsByTagName("head")[0];
var cssNode = document.createElement('link');
cssNode.type = 'text/css';
cssNode.rel = 'stylesheet';
cssNode.href = 'jqueryjava.css';
headID.appendChild(cssNode);
</script>

Adding a second submit handler

I am trying to modify an existing web page which looks like this
<script type="text/javascript" src="s1.js"></script>
s1.js has something like this
window.onDomReady = DomReady;
function DomReady(fn)
{
if(document.addEventListener)
{
document.addEventListener("DOMContentLoaded", fn, false);
}
else
{
document.onreadystatechange = function(){chState(fn);};
}
}
function chState(fn)
{
if(document.readyState == "interactive" || document.readyState == "complete")
fn();
}
window.onDomReady(addHndlrs);
function addHndlrs()
{
var forms = document.getElementsByTagName("form");
for(var i = 0; i < forms.length; i++)
{
var form = forms[i];
if(form.addEventListener)
{
form.addEventListener("submit", DoValidate, false);
}
else if (form.attachEvent)
{
form.attachEvent("onsubmit", DoValidate);
}
Other stuff.
}
When I click Submit on the form, DoValidate does called.
I am trying to modify this page to add another submit handler which is called after the first one.
I copied the above code, changed function names & put into s2.js.
window.onDomReady = DReady;
function DReady(fn)
{
if(document.addEventListener)
{
document.addEventListener("DOMContentLoaded", fn, false);
}
else
{
document.onreadystatechange = function(){Chk1State(fn);};
}
}
function Chk1State(fn)
{
if(document.readyState == "interactive" || document.readyState == "complete")
fn();
}
window.onDomReady(myready);
function myready()
{
var forms = document.getElementsByTagName("form");
for(var i = 0; i < forms.length; i++)
{
var form = forms[i];
if(form.addEventListener)
{
form.addEventListener("submit", mynewhandler, false);
}
else if (form.attachEvent)
{
form.attachEvent("onsubmit", mynewhandler);
}
}
}
In the form html, I added a reference to it
<script type="text/javascript" src="s1.js"></script>
<script type="text/javascript" src="s2.js"></script>
My new submit handler never gets called. I debugged it through firebug - I see DReady being called and my DOM Ready handler being registered. However myready never gets called, so my submit handler never gets registered.
What am I missing here? I tried changing order of inclusion of s1.js and s2.js but that doesn't seem to help. I want to do this without modifying s1.js
The code you provided seems to be fine! Have checked in Chrome 25, FireFox 19 and IE 10!
Normally I find it easier to just modify the code at runtime (not the source file), thanks to JavaScript being dynamic typed, you could overwrite the DoValidate function with your own, passing it the original DoValidate through closure in the s2.js:
var originalValidate = DoValidate;
DoValidate = function () {
originalValidate();
alert("my handler");
};

Categories