在WEB開發過程當中,咱們會常常的遇到各類事件監聽以及事件處理的狀況。javascript
事件(Event)即爲用戶的動做,例如:用戶點擊鼠標,產生onclick事件;按下鍵盤,產生onkeyDown事件;改變輸入框的值,產生onchange事件...html
W3C標準規定,事件是做爲函數的參數傳入的,例如:前端
<p id="demo"> <a>點擊我將得到節點1</a> <a>點擊我將得到節點2</a> </p> <script type="text/javascript"> document.getElementById("demo").onclick=function(e) { alert(e.target); } </script>
當在元素上點擊時,彈出警告框,內容爲點擊我將得到節點。這裏函數傳入的參數e,就是事件。瀏覽器會實時的根據用戶點擊的a標籤的不一樣返回不一樣的節點內容。java
這種作法在FireFox、Chrome、Safari等遵循W3C規範的瀏覽器下是沒有問題的,惟獨在IE(暫時僅限於8.0如下版本)下是行不通的,IE採用了一種非標準的方式,並非將事件做爲函數參數傳入,而是將事件做爲window對象的event屬性:window.event傳遞進去的;並且,IE使用的是event.srcEvent來獲取目標事件... git
既然IE8如下不行,那有什麼方法解決這個問題尼?
上面其實涉及到JS事件的兼容性問題,下面咱們將從事件處理的角度來慢慢的分析這個問題。github
固然,仍是老話,全部的方法都來自網上,學到了纔是本身的!!瀏覽器
而後,寫在前面,帶上咱們可愛的小夥伴。廢話很少說,下面咱們開始看起吧!性能優化
文章主要是對js的this進行簡單的說明和介紹,順帶會添加一些代碼,沒辦法,語言能力有限,說明不了的只能直接上代碼了。dom
IE瀏覽器從IE9開始已經支持DOM2事件處理程序,可是對於老版本的ie瀏覽器,任然使用attachEvent方式來爲dom元素添加事件。值得慶幸的是微軟已宣佈2016年將再也不對ie8進行維護,對於廣大前端開發者無疑是一個福音。然而在曙光來臨以前,仍然須要對那些不支持DOM2級事件處理程序的瀏覽器進行兼容性處理。
嘛,下面,將慢慢的處理事件在常規狀況下(額,就是W3C和IE)的處理方式。ide
借鑑GitHub上markyun寫的事件偵聽器函數實現。下面我只是作一些註釋性說明
// event(事件)工具集,來源:https://github.com/markyun markyun.Event = { // 頁面加載完成後 // 主要是原生JS,頁面只能加載一次window.onload;這裏使用該方法能夠綁定多個方法。 readyEvent : function(fn) { if (fn==null) { fn=document; } var oldonload = window.onload; if (typeof window.onload != 'function') { window.onload = fn; } else { window.onload = function() { oldonload(); fn(); }; } }, // 視能力分別使用dom0||dom2||IE方式 來綁定事件 // 下面的順序:標準dom2,IE dom2, dom // 參數: 操做的元素,事件名稱 ,事件處理程序 addEvent : function(element, type, handler) { if (element.addEventListener) { //事件類型、須要執行的函數、是否捕捉 element.addEventListener(type, handler, false); } else if (element.attachEvent) { element.attachEvent('on' + type, function() { handler.call(element); }); } else { element['on' + type] = handler; } }, // 移除事件 removeEvent : function(element, type, handler) { if (element.removeEnentListener) { element.removeEnentListener(type, handler, false); } else if (element.datachEvent) { element.detachEvent('on' + type, handler); } else { element['on' + type] = null; } }, // 阻止事件 (主要是事件冒泡,由於IE不支持事件捕獲) stopPropagation : function(ev) { if (ev.stopPropagation) { ev.stopPropagation();// 標準w3c } else { ev.cancelBubble = true;// IE } }, // 取消事件的默認行爲 preventDefault : function(event) { if (event.preventDefault) { event.preventDefault();// 標準w3c } else { event.returnValue = false;// IE } }, // 獲取事件目標 getTarget : function(event) { // 標準W3C 和 IE return event.target || event.srcElement; }, // 獲取event對象的引用,取到事件的全部信息,確保隨時能使用event; getEvent : function(e) { var ev = e || window.event; if (!ev) { var c = this.getEvent.caller; while (c) { ev = c.arguments[0]; if (ev && Event == ev.constructor) { break; } c = c.caller; } } return ev; } };
IE下的事件特例
IE下的事件對象是在window下的,而標準應該做爲一個參數, 傳爲函數第一個參數;
IE的事件對象定義的屬性跟標準的不一樣,如:
cancelBubble
默認爲false
, 若是爲true
就是取消事件冒泡; returnValue
默認是true
,若是爲false
就取消默認事件; srcElement
, 這個指的是標準W3C下的獲取事件目標target
,Firefox下的也是srcElement
;
以上的全部方法,都來自網上。
全部的方法,都必須腳踏實地,在具體應用場景下去分析、去選擇,咱們應該按照具體的狀況,來選擇方法。
由於瀏覽器的多樣性,前端的應用場景常常很複雜,性能優化充滿挑戰,也充滿機遇。
學會了纔是本身的,知道會用會寫,纔是咱們最終的目標。