Mik*_*ike 3 javascript event-handling onload
我有两个js文件,每个文件都有自己的window.onload处理程序。根据我将两个onload处理程序附加到窗口对象的方式,我在第二个处理程序上得到了不同的行为。
更具体地说,这是我的html文件:
<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>
Run Code Online (Sandbox Code Playgroud)
它加载两个js文件,script1.js和script2.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;
}
Run Code Online (Sandbox Code Playgroud)
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;
}
}
Run Code Online (Sandbox Code Playgroud)
在Script2.js中,我尝试使用addOnloadHandler()函数以一种不错的非侵入性方式添加第二个onload处理程序。该函数不对是否已将任何onload处理程序附加到window对象进行任何假设。它是非侵入性的,因为它应该添加新的处理程序而不删除先前的处理程序。
事实是,在使用addOnloadHandler()加载时,initAll2()无法检测到document.getElementById(“ redirect”)已经附加了foo()作为onclick事件处理程序的事实(请参阅initAll1())。警报消息“错误!” 被触发,在我看来这是错误的行为。
当我忘记addOnloadHandler()并使用以下命令将两个onload处理程序附加到Script1.js中时:
window.onload = function () {initAll1(); initAll2();};
Run Code Online (Sandbox Code Playgroud)
然后一切都按预期工作,并且initAll2()启动“正确!” 警报消息。
addOnloadHandler()有什么问题吗?有人可以使它工作吗?我真的很想用它代替第二种方法。
谢谢!
万一将来人们发现这一点,并正在寻找一种方式来使用多个事件处理程序时,对象本身不支持addEventListener,attachEvent或者听者堆放一些其他形式的-也就是说,它是一个定制的对象,妥善执行。然后,您可以执行以下操作:
object.onload = (function(pre){
return function(){
pre && pre.apply(this,arguments);
/// do what you need for your listener here
}
})(object.onload);
Run Code Online (Sandbox Code Playgroud)
每次使用上面的代码时,都会将以前的onload侦听器作为参数传递,并且在触发新的侦听器时,它将首先运行旧的侦听器-意味着,如果您愿意,可以像这样堆叠许多侦听器。但是,仅在以上代码始终用于向对象添加侦听器的情况下,此方法才有效。如果用其他简单的方法覆盖了所有其他工作,那么所有的辛苦工作都将被撤消:
object.onload = function(){}
Run Code Online (Sandbox Code Playgroud)
作为对程序员的注释,如果您要实现库,插件或构造函数,则其他程序员可能会接管您的工作。请,请为多个事件侦听器编写功能。确实没有那么困难。