addLoadEvent 函数,其实是用于页面内触发 onload 事件时执行多个任务。
首先来梳理一下函数代码。
function addLoadEvent(func){
//将函数作为参数,此函数就是 onload 触发时需要执行的某个函数
var oldonload=window.onload;
//将原来的 onload 的值赋给临时变量 oldonload。
if(typeof window.onload!="function"){
//判断 onload 的类型是否是 function。如果已经执行window.onload=function(){...} 赋值,那么此时 onload 的类型就是 function
//否,则说明 onload 还没有被赋值,当前任务 func 为第一个加入的任务
window.onload=func();
//作为第一个任务,给 onload 赋值
}else{
//是,则说明 onload 已被赋值,onload 中先前已有任务加入
window.onload=function(){
oldonload();
func();
//作为后续任务,追加到先前的任务后面
}
}
}
那么,再来看一个实例。假如需要在 onload 时执行两个任务,分别为 func1 和 func2。
function func1(){
//...
}
function func2(){
//...
}
如果不用 addLoadEvent 函数,那么很有可能会出现下面这样错误的写法。
// do something
window.onload=func1();
// do something
window.onload=func2();
这样的后果就会是,onload 的值会被最后一次赋值覆盖,func1 将不会执行,只会执行 func2。
所以正确的写法应该是:
window.onload=function(){
func1(); // 我们人为判断 func1 是第一个任务
func2();
}
以上就是 addLoadEvent 函数流程的最简单形式。出于功能模块封装的考虑,我们将判断 onload 是否被赋值的功能交由模块内部处理,因此形成了这个函数。很明显,最佳的写法就是:
// do something
addLoadEvent(func1);
// do something
addLoadEvent(func2);
至于你问为什么其中 func 和 oldonload 可以要又可以不要,是误解了这个函数的意义,请仔细理解一下函数代码,特别是那个判断分支的作用。oldonload 只在 onload 已经被赋值(即至少已经有一个任务)的情况下才有效,它只是起一个传递作用——将原有 onload 的值(即之前的一个或多个任务)放在后续任务之前;而 func 作为函数的形参,代表向函数输入的任意实参,即后续任务。