論如何做好IE和Chrome互毆時的一條好池魚之事件綁定篇

來源:互聯網
上載者:User

標籤: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互毆時的一條好池魚之事件綁定篇

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.