Adding multiple onload handlers

I have two js files, each of which has its own window.onload handler. Depending on how I attach the two load handlers to the window object, I get a different behavior in the second handler.

In particular, 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"> <a href="http://www.whatever.com" id="redirect"> Wellcome to our site... c'mon in! </a> </h2> </body> </html> 

It loads two js files, script1.js and script2.js.

Here is a version of these two scripts that leads to unexpected behavior (at least to me).

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 a second onload handler in a beautiful non-invasive way using the addOnloadHandler () function. This function makes no assumptions as to whether there is already a load handler attached to the window object. This is non-invasive because it must add a new handler without deleting the previous ones.

The fact is that when loading with addOnloadHandler (), initAll2 () is not able to detect the fact that document.getElementById ("redirect") already has foo () attached as an onclick event handler (see initAll1 ()), Warning message β€œwrong!”, which seems to me to be wrong behavior.

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 () starts "correctly!". warning message.

Is there something wrong with addOnloadHandler ()? Can anyone make it work? I would really like to use it instead of the second method.

Thanks!

+3
source share
4 answers

Just in case, future people find this and are looking for a way to use several event handlers when the object itself does not support addEventListener , attachEvent or any other form of stacking the listener - that is, it is a custom-made object that is poorly 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 as an argument, and when your new listener starts, it starts the old listener in the first place - this means that you can add many listeners like this if you wish, However, this will only work as long as the above code is always used to add listeners to your object. All your hard work will be canceled if it is redefined in another place simple:

 object.onload = function(){} 

As a note for coders, if you want to implement a library, plug-in or constructor, and it is possible that other coders will take over your work. Please request a code for multiple event listeners. It really is not that difficult.

+4
source

You need to look at addEventListener and attachEvent , which are built-in implementations of your addOnloadHandler .

+2
source

The PPK link to addEventListener explains how this is done pretty well:

http://www.quirksmode.org/js/events_advanced.html

+1
source

Thanks for answers!

I rewrote my script2.js file 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 built-in implementations you guys mentioned. I left script1.js untouched.

The received code still does not work (that is, the warning message β€œwrong!” Is displayed). It only works when I register the onload initAll1 () handler twice, 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); 

not working fine.

Is there a way around this problem that does not involve touching script1.js?

Just in case, you are wondering why I don’t want to touch script1.js, the reason is because I want my code (script2.js) to be reused in other projects, no matter what other js files each project uses. Thus, it should work with all possible event logging methods used in script1.js.

Thanks again for your help!

+1
source

Source: https://habr.com/ru/post/923664/


All Articles