传统方法:
且看下面代码,
function addLoadEvent(func){
var oldload=window.onload;
if(typeof window.onload!="function"){
window.onload=func;
}else{
window.onload=function(){
oldload();
func();
}
}
}
至此,使用addLoadEvent方法可以不断地为window.onload事件添加方法。
另外,把这个函数小改一番便可以使用到其他事件上。
DOM 2 提供的新的api
node.addEventListener方法。
具体看代码:
var btn=document.getElementById("btn");//btn是一个按钮
btn.addEventListener("click",doSomething1,false);
btn.addEventListener("click",doSomething2,false);
于是,点击btn按钮,会执行两个方法。
貌似问题得到圆满解决,可惜不是。因为IE会跳出来说:“IE没有这个方法”。
在IE上的实现是这个样子的:
var btn=document.getElementById("btn");//btn是一个按钮
btn.attachEvent("onclick",doSomething1);
btn.attachEvent("onclick",doSomething2)
功能上完全一样的两个函数,名字不同,参数不同。(注意,addEventListener是“click”,attachEvent是“onclick”)
怒摔。
虽然这是个很容易就解决的问题,但总要被坑一把才能发现。IE和chrome打架真是殃及无数池鱼。
我们聪明机智的程序员总可以用经典思路去解决这种“经典问题”:
function addEventLoad(node,func){
if(node.addEventListener){
node.addEventListener("click",func,false);
}
if(node.attachEvent){
node.attachEvent("onclick",func);
}
}
或者再进一步:
function addEventLoad(object,eventName,func){
if(object.addEventListener){
object.addEventListener(eventName,func,false);
}
if(object.attachEvent){
object.attachEvent("on"+eventName,func);
}
}
继续深入(重要)
看看btn的代码:
<button id="btn" title="this is a button">btn</button>
然后是两个事件函数的代码:
function do1(){
alert(this.title);
}
function do2(){
alert(this.title);
}
然后放出整个测试页面的代码:
<!DOCTYPE HTML>
<html>
<head>
<script>
window.onload=function(){
var btn=document.getElementById("btn");
btn.onclick=function(){
alert("btn1");
};
addEventLoad(btn,do1);
addEventLoad(btn,do2);
}
function addEventLoad(node,func){
if(node.addEventListener){
node.addEventListener("click",func,false);
}
if(node.attachEvent){
node.attachEvent("onclick",func);
}
}
function do1(){
alert(this.title);
}
function do2(){
alert(this.title);
}
</script>
</head>
<body>
<button id="btn" title="this is a button">btn</button>
</body>
</html>
此页面在chrome上运行,点击按钮会弹出3个警告框,分别是:
“btn1”,“this is a button”,“this is a button”
但在IE上运行则是:
“btn1”,“undefined”,“undefined”
IE真是虐我千百遍。
经查阅:IE没有实现DOM Level 2(比如document.addEventListener就属于DOM Level 2)。IE有自己的事件处理框架。所以在IE中,事件处理函数为这个事件框架所有,而不属于XHMLT页面上通过点击事件或鼠标移动事件激活的一个对象。也就是说,do1和do2中的this关键字,在chrome中就是指那个按钮,在IE中就是指IE事件框架。
至此,看起来问题难以解决,真是绝望。
但正所谓天无绝人之路,其实,事件处理程序会从attachEvent()和addEventListener()得到一个Event对象,这个对象有两个很有用的属性:
“type”:提供所触发事件的事件名,比如“click”
“target”:指向事件的目标,即页面上被激活的对象
然后,我们发现问题又来了:chrome和ie的这个Event对象是不同的。在chrome中Event对象的target,在ie中则是srcElement。
但这难不倒我们,看下列函数:
function getActiveObject(e){
var obj;
if(!e){ //较早版本的IE不会发送这个对象
obj=window.event.srcElement;
}else if(e.srcElement){
obj=e.srcElement;
}else{
obj.e.target;
}
return obj;
}
其中e就是那个Event对象。
另外,为了让事件处理函数使用这个Event对象,我们需要在其参数列表上加一个变量,比如这样
do1(e){}
然后我们看看经过修改的完整测试页面:
<!DOCTYPE HTML>
<html>
<head>
<script>
window.onload=function(){
var btn=document.getElementById("btn");
btn.onclick=function(){
alert("btn1");
};
addEventLoad(btn,do1);
addEventLoad(btn,do2);
}
function addEventLoad(node,func){
if(node.addEventListener){
node.addEventListener("click",func,false);
}
if(node.attachEvent){
node.attachEvent("onclick",func);
}
}
function do1(e){
var obj=getActiveObject(e)
alert(obj.title);
}
function do2(e){
var obj=getActiveObject(e)
alert(obj.title);
}
function getActiveObject(e){
var obj;
if(!e){ //较早版本的IE不会发送这个对象
obj=window.event.srcElement;
}else if(e.srcElement){
obj=e.srcElement;
}else{
obj.e.target;
}
return obj;
}
</script>
</head>
<body>
<button id="btn" title="this is a button">btn</button>
</body>
</html>
至此,此页面在Chrom和IE上都可以得到想要的东西。