动态的网页往往会使用Javascript来对页面元素进行一些操作,比如为某个按钮绑定一个点击事件,或者给某个输入框添加获得焦点后的事件。因为页面内容自上而下顺序被读取,当程序运行至某段Javascript代码时,其想要操作的Html元素可能尚在赶来的途中,代码无法准确定位到需要操作的元素,后续行为自然也难以为继了。为了确保页面上的Javascript代码能够稳定运行,我们需要确保代码运行前,Html文档已经正确被加载。window.onload就是这样一个事件,在文档加载完成后能立即触发,并且能够为该事件注册事件处理函数。我们可以把页面正确加载后需要执行的Javascript函数一股脑的塞给它,就像这样:
/*========
window.onload
========*/
window.onload=function(){
Func1();
Func2();
Func3();
.....
}
事件处理函数addLoadEvent
这样做的不便之处在于,每一个新函数被定义,都需要回滚到window.onload的位置重新添加。想象一下项目文件较大,新函数与事件处理函数相隔几条街的情况,如果不幸这个项目改动还比较频繁,那这样的来回修改也会耗费不少的时间。为了减少这样的重复操作,在《JavaScript DOM编程艺术》一书中,给出了这样一个代替方案:
/*========
事件处理函数
========*/
function addLoadEvent(func){
var oldonload = window.onload;
if (typeof window.onload != 'function'){
window.onload = func;
} else {
window.onload = function(){
oldonload();
func();
}
}
}
上面这段函数对window.onload进行了封装,利用addLoadEvent函数,我们可以在js语句或js文件的任意位置,将新增的某个函数加入事件处理的队列,只需要将函数名称作为参数传递给addLoadEvent:
/*========
事件处理示例
========*/
function fun1(){
console.log('hello world!');
}
addLoadEvent(fun1);
让addLoadEvent传递参数
addLoadEvent为事件处理提供了便利,但由于它只支持传入函数的名称,遇到需要传递参数的场合,就有点捉襟见肘了。为了能够让addLoadEvent支持传参,我们需要对函数进行一些改动:
/*========
含参事件处理
========*/
function addLoadEventArgs(func) {
var args = [].slice.call(arguments,1);
var oldonload = window.onload;
if (typeof window.onload != 'function') {
window.onload = function() {
func.apply(this,args);
}
} else {
window.onload = function() {
oldonload();
func.apply(this,args);
}
}
}
函数第二行的arguments是我们运行函数时所传入的参数,该行语句会摘除第一个参数——也就是我们所需要运行的函数名,将其后的1个或多个参数存入数组,待文档调用完毕,函数可以执行时再将此数组传递给需要运行的函数:
/*========
含参事件示例
========*/
function test1(a){
console.log(a);
}
function test2(a,b) {
console.log(a+b);
}
addLoadEventArgs(test1,'hello');
addLoadEventArgs(test2,3,2);