標籤:style os 使用 io ar 問題 cti 代碼 html
傳統方法:
且看下面代碼,
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上都可以得到想要的東西。
論如何做好IE和Chrome互毆時的一條好池魚之事件綁定篇