問題描述
我有兩個 js 文件,每個都有自己的 window.onload 處理程序.根據我將兩個 onload 處理程序附加到窗口對象的方式,我在第二個處理程序上得到不同的行為.
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.
更具體地說,這是我的 html 文件:
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">
<a id="redirect"> Wellcome to our site... c'mon in! </a>
</h2>
</body>
</html>
它加載了兩個js文件,script1.js和script2.js.
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:
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:
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;
}
}
在 Script2.js 中,我嘗試使用函數 addOnloadHandler() 以一種很好的非侵入性方式添加第二個 onload 處理程序.此函數不對窗口對象是否已附加任何 onload 處理程序做任何假設.它是非侵入性的,因為它應該添加新的處理程序而不刪除以前的處理程序.
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.
問題是,當使用 addOnloadHandler() 加載時,initAll2() 無法檢測到 document.getElementById("redirect") 已經將 foo() 作為 onclick 事件處理程序附加的事實(請參閱 initAll1()).警告信息錯誤!"被觸發,對我來說這似乎是錯誤的行為.
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.
當我忘記 addOnloadHandler() 并在 Script1.js 中附加兩個 onload 處理程序時,使用:
When I forget about addOnloadHandler() and attach both onload handlers in Script1.js using:
window.onload = function () {initAll1(); initAll2();};
然后一切都按預期工作,并且 initAll2() 啟動正確!"提示信息.
then everything works as expected, and initAll2() launches the "correct!" alert message.
addOnloadHandler() 有什么問題嗎?有人可以讓它工作嗎?我真的很想用它來代替第二種方法.
Is there something wrong about addOnloadHandler()? Could anybody make it work? I would really like to use it instead of the second method.
謝謝!
推薦答案
以防萬一將來人們發現這個,并且正在尋找一種在對象本身不支持時使用多個事件處理程序的方法 addEventListener
、attachEvent
或某種其他形式的監聽器堆棧——即它是一個定制對象,實施不當.然后您可以執行以下操作:
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);
每次您使用上述代碼時,前一個 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.
這篇關于添加多個 onload 處理程序的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!