不要再吹水地球人聽不懂的技術,咱來點乾貨!–中文前端UI架構Kit(三)揭開進階事件管理的神秘面紗

來源:互聯網
上載者:User

從今天這章開始,我將會著重介紹KitJs的事件管理的內容,盡量用淺顯的語言給大家揭露主流的js架構是如何在內部實現自己獨立的事件管理功能的。

kitjs Demo地址:http://xueduany.github.com/KitJs/KitJs/index.html

Source Code:https://github.com/xueduany/KitJs 
 

(一)普通的Dom事件

我們一般可以通過支援在HTML寫上事件

<a onclick=”alert(1)”>測試</a>

或者取到dom對象後綁定

document.getElementById(‘a’).onclick=function(){alert(1)}

或者二級事件

document.getElementById(‘a’).addEventListener(‘click’,function(){alert(1)},flase)

或者通過script tag

<script for=”a” event=”onclick”>alert(1)</script>

而W3C標準推薦的是以上的第三種方式綁定,既二級事件的方式,目的是解耦HTML與Js的強依賴

(二)問題

但是如果我們僅僅直接使用方式3的方式進行我們的Js編程的話,還是不夠的,因為會遇到以下問題

1. 瀏覽器安全色性,IE系列和W3C支援的瀏覽器對於二級事件綁定的方式名,參數都不一致

2. 通過2級事件綁定之後,你無法知道別人對於同一個元素有沒有綁定過事件,綁定了哪些事件,事件內容是什嗎?

3. 通過2級事件綁定的方法觸發後,順序不是按照綁定之前的先後順序,是隨機執行的,可有些時候,我們需要對於觸發的方法按照順序

4. 當同一個元素的事件被觸發之後,沒有w3c的標準api支援對於同一個元素繫結著的其他事件停止繼續觸發,w3c支援停止冒泡

5. 很多時候,我們是通過匿名函數的方法註冊2級事件的,沒有留下註冊事件執行方法的控制代碼,所以很難通過removeEventListener登出該事件

(三)Kit如何解決

ok,js架構就是為瞭解決以上問題而存在的,讓我們看看kit是如何處理以上問題的。

在kit.js的api中,存在一個ev(config)方法

該方法接受一個Map類型的object,裡面存在了4個重要參數,

el 需要綁定的元素

String 事件類型

fn 觸發執行的方法

scope 可以省略,是否需要指定this指標,如無,則傳入註冊時的el作為this指標

(四)代碼解析

讓我們進一步看看代碼實現

直接從核心部分看起

如果傳入參數不為空白,那個在傳入參數的el上建立一個對象,用於儲存KitJs的事件註冊evReg

evReg對象裡面有兩個子物件,一個叫做evRegEv,儲存註冊的事件

在evRegEv對象裡面,儲存一個key為當前註冊事件,value為一個數組,數組裡面按照先來後到的順序放入方法ev傳入的config參數,注意了,這個是一個數組!!!因為數組可以儲存先後順序,這一點非常重要

還有一個叫做evRegFn,儲存事件觸發的匿名方法,

我們可以看到evRegFn是一個匿名事件,在開頭,他會判斷一下global的變數window[me.CONSTANTS.KIT_EVENT_STOPIMMEDIATEPROPAGATION]是否==true,如果是true的話,即會返回,不會再繼續執行

接著往下看,他會接受到事件觸發的EV對象,給這個EV用mergeIf的方式附加很多個物件,像target,currentTarget,relatedTarget是為瞭解決瀏覽器安全色性的問題

而stopNow,stopDefault,stopGoOn是為了阻止事件繼續觸發而建立的方法。

下面這段就是evRegFn的關鍵了,我們會迴圈之前建立的那個evRegEv裡面的事件數目組,按照先後順序,取出之前的ev方法傳入的config參數,執行config參數裡面方法,如果方法的傳回值不為空白,則返回他的傳回值

最後做一個瀏覽器安全色,用2級事件的方式,綁定我們的evRegFn匿名方法。

(五)小結

簡單來說,Kit用一個自己的匿名方法,緩衝了事件註冊的控制代碼,到一個數組裡面,這樣就可以記住事件的先後順序,以及提供入口找出之前註冊的事件,參數,方法等等,同時針對瀏覽器安全色性做了相容。

(六)登出事件

有了Kit幫忙緩衝事件控制代碼,登出就變得簡單了

你可以看到Kit通過直接對比,或者fn.toString對比,以及fn.toString().trim()的方式對比來找到對應的事件config,從數組中刪除

(七)事件增強

大家剛才也應該留意到Kit對於系統的Event對象做了一個mergeIf的操作,首先為什麼要做megerIf,因為系統的Event的對象屬性是Readonly的,不能覆蓋,只能添加他沒有的屬性

所以Kit只能megerIf,我們都知道各個瀏覽器的事件對象Event Object存在一個不相容性,所以就需要Kit去fix這些不相容,比如IE沒有target屬性,只有srcElement,我們可以給他加上target屬性,實現W3c標準的相容

當然了,僅僅的修複是不能滿足我們的需求的,很多時候,我們還需要給Event對象做一點小小的增肥

比如在iphone的touchdown,touchmove開發的時候,我們經常要取到單指的offset,而取單指的offset,又需要ev.targetTouches[0].clientX,這樣的代碼,但是一旦在匿名函數這樣了,在PC上又不相容了,

怎麼辦呢,沒有關係,我們可以給Event Object mergeIf我們自己的屬性

firstFingerClientX等等,這樣我們就可以很簡單的實現移動端,PC端開發的代碼統一了。

包括,下一篇要說HTML5拖拽,進階手勢事件都是基於這一基礎之上架構的。

補充一下,為什麼不像ExtJs那樣new一個自己的Event,是因為

1. 系統原生的對象,有一定的繼承關係,不想破壞

2. 如果用自己的new Object,可能會造成代碼脫離架構之後,不可移植性,需要再次改變代碼內容 

 

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.