js框架開發之旅--事件

這一篇我們將介紹事件的工作原理,和不同的框架中事件的實現方法,以及事件接口的設計。我會在最後選擇一種接口的設計,來實現我們的事件功能。


原理

事件和Javascript的關係非常密切,你可以想象如果沒有事件,頁面怎麼和用戶進行交互。Javascript一出現的時候,就已經有事件功能了。最早的事件處理時寫在html代碼裏的,如下:
<a href="/" οnclick="alert('Hello World!')">
你之前一定見過這樣的寫法。它最早出現在Netscape瀏覽器裏,由於Netscape的早期版本如此的受歡迎,微軟也實現了與Netscape相兼容的事件。
上面的代碼在Javascript代碼裏是這樣的:
// assume 'element' is the previous link minus the onclick
element.onclick = function() { alert('Hello World!'); };


訪問事件對象

我們可以用下面方法訪問事件對象:
function handler(event) {
    if (!event) var event = window.event;
}
window.event是微軟特有的屬性,用來記錄上一次的事件對象。在一般的程序中,這種做法非常危險,會造成訪問衝突。但是Javascript是單線程的,這種方法在Javascript中是安全的可信賴的。
jQuery中是這樣做的:
handle: function( event ) {
  var all, handlers, namespaces, namespace_sort = [], namespace_re, events, args = jQuery.makeArray( arguments );
  event = args[0] = jQuery.event.fix( event || window.event );


停止事件

我曾經被默認事件和事件冒泡搞的比較亂,我之前一直以爲停止一個事件就是把一切都停止了。但是,在這裏不是這樣的。
默認事件
在一個事件處理方法裏返回false可以阻止默認事件:
element.onclick = function() { alert('Hello World!'); return false; };
如果是個a標籤,就不會跳到對應的鏈接了。
捕獲和冒泡
如果我們把onclick事件綁定在兩個元素上,其中一個是另一個的父節點,我們很難弄清楚哪個方法會優先執行。不同的瀏覽器有不同的處理方式。然而,幸運的是我們並不經常會遇到這樣的問題,我們更多的是去阻止事件傳播。
function handler(event) {
    if (!event) var event = window.event;
    event.cancelBubble = true;
    if (event.stopPropagation) event.stopPropagation();
}
到目前爲止,據我所知,只有IE使用cancelBubble,大部分都使用 stopPropagation。

jQuery及其他大部分框架都使用類似上面的原理阻止事件冒泡。


綁定多個事件

當涉及到多個事件的綁定,就比單個事件麻煩了:
element.onclick = function() { alert('Hello World!'); return false; };
element.onclick = function() { alert('This was the best example I could think of'; return false; };
上面的例子重新綁定了onclick,而不是添加了一個新的方法。

我們也不能簡單的把所有的事件方法都放到同一個方法裏調用,因爲我將來可能要刪除其中的一些方法。


框架的接口設計

事件框架的工作是簡化事件的操作,並使之跨平臺。我們要做如下的事情:
  • 統一事件名稱,如onClick事件應該變成click
  • 簡化事件的註冊和刪除
  • 跨平臺的封裝event對象
  • 對冒泡的簡化
  • 提供跨平臺的鍵盤和鼠標的交互
  • 彌補一些瀏覽器的不足,如IE的內存泄露

jQuery的事件

jQuery基於W3C標準實現的事件功能,對瀏覽器的差異(尤其是IE瀏覽器)進行了封裝。
jQuery把事件功能封裝到了內部的DOM對象列表上,接口使用非常簡單。
$('a').click(function(event) {
  alert('A link has been clicked');
});
上面的代碼把click事件綁定到所有的連接上。
  • 通過event.target可以獲取事件元素。
  • 如果是冒泡事件,我們可以通過event.currentTarget獲取當前元素,或者通過this對象訪問。
  • 通過調用event.preventDefault()阻止默認事件
  • 通過調用event.stopPropagation()阻止事件冒泡
  • 通過$('a').unbind('click')刪除事件的綁定
  • 通過$('a').trigger('click')觸發事件


Dojo

Dojo的事件實現基於函數間的connections,註冊事件的方法如下:
dojo.connect(dojo.byId('a#hello'), 'onclick', function(event) {
  alert('Hello World!');
});
dojo保持了原理的事件名稱,event和其他框架一樣是做過跨瀏覽器處理的。
dojo使用dojo.disconnect()解除事件綁定,其他方法跟jQuery基本一樣。

通過和幾個框架比較發現jQuery的事件實現的最漂亮,因此我們下一篇會借鑑jquery的接口設計,實現我們的事件框架。


牧客網--讓自由職業變成一個靠譜的工作


發佈了16 篇原創文章 · 獲贊 87 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章