開發模組化的JavaScript組件

來源:互聯網
上載者:User

現如今,雖然多數的web應用都使用了大量的JavaScript,但如何保持用戶端功能的專註性、健壯性和可維護性依然是一個很大的挑戰。

儘管其它程式設計語言和系統都已經將關注分離和DRY這樣的基本原則視為理所當然的宗旨,但往往在進行瀏覽器端應用開發的時候,這些原則就被忽視了。

造成這一現象的部分原因是JavaScript語言本身就在不斷掙紮的曆史,在很長的一段時間內,它都難以獲得開發人員的認真關注和對待。

而更重要的原因或許是源於服務端與用戶端的差異造成的。雖然在這方面已經有大量的架構風格方面的概念,例如ROCA,闡述了如何管理這種差異的方式。但還是缺乏如何?這些概念的具體步驟的指南1。

這些原因經常導致前端代碼的高度過程化並且相對缺乏結構性,這種直接的代碼調用方式減少了調用的開銷,從而簡化了代碼調用的複雜性,JavaScript和瀏覽器也是因為這一點原因而允許這種調用方式的存在。但很快,通過這種方式實現的代碼就會變得得難以維護。

本文將通過一個樣本為你展示某個簡單的組件(widget)的演化過程,看看它是如何從一個龐大的、缺乏結構性的程式碼程式庫進化為一個可重用的組件的。

對連絡人進行過濾

這個樣本組件的作用是對一個連絡人清單通過名稱進行過濾。它的最新成果以及它的全部演化過程都可以在這個GitHub程式碼程式庫中找到。我們鼓勵讀者們對提交的代碼進行審閱,並且留下寶貴意見。

按照漸進式增強原則,我們首先從一個基礎的HTML結構開始以描述所用到的資料。這裡用到了h-card這個微格式(microformat),它能夠起到語義化的作用,使得連絡人的各種資訊顯得具有意義:

<!-- index.html -->    <ul>    <li class="h-card">            <img src="png/jake.png" alt="avatar" class="u-photo">             <a href="http://jakearchibald.com" class="p-name u-url">Jake Archibald</a>            (<a href="mailto:jake@example.com" class="u-email">e-mail</a>)         </li>        <li class="h-card">            <img src="png/christian.png" alt="avatar" class="u-photo">             <a href="http://christianheilmann.com" class="p-name u-url">Christian Heilmann</a>            (<a href="mailto:christian@example.com" class="u-email">e-mail</a>)        </li>        <li class="h-card">            <img src="png/john.png" alt="avatar" class="u-photo">             <a href="http://ejohn.org" class="p-name u-url">John Resig</a>             (<a href="mailto:john@example.com" class="u-email">e-mail</a>)        </li>        <li class="h-card">             <img src="png/nicholas.png" alt="avatar" class="u-photo">             <a href="http://www.nczonline.net" class="p-name u-url">Nicholas Zakas</a>             (<a href="mailto:nicholas@example.com" class="u-email">e-mail</a>)        </li>     </ul>

有一點請注意,在這裡我們並不關心這個DOM結構是基於server端產生的HTML代碼,或是由其它組件產生的,只要保證在初始化時,我們的組件能夠依賴於這個基礎結構就夠了。這一結構實際上為表單項構成了一個基於DOM的資料結構 [{ photo, website, name, e-mail }]。

有了這個基礎結構之後,我們就可以開始實現我們的組件了。第一步是為使用者提供一個輸入欄位,以輸入連絡人名稱。雖然它並不屬於DOM結構的契約,但我們的組件仍然要負責建立它並動態地加入到DOM結構中去(畢竟,如果沒有我們的組件,那麼添加這個欄位就完全沒有任何意義了)。

// main.js      var contacts = jQuery("ul.contacts");      jQuery('<input type="search"  />').insertBefore(contacts);

(我們在這裡僅是出於便利性而使用了jQuery,同時也考慮到它的廣泛使用性。如果使用其它的DOM操作類庫,也是出於同樣的原因。)

這個JavaScript檔案本身以及它所依賴的jQuery檔案都會在HTML檔案的底部進行引用。

接下來開始加入所需的功能,對於那些不符合這個建立的欄位中的輸入名稱的連絡人,這個組件會將它們隱藏起來:

// main.js      var contacts = jQuery("ul.contacts");      jQuery('<input type="search"  />').insertBefore(contacts).on("keyup", onFilter);      function onFilter(ev) {          var filterField = jQuery(this);          var contacts = filterField.next();          var input = filterField.val();          var names = contacts.find("li .p-name");          names.each(function(i, node) {              var el = jQuery(node);              var name = el.text();              var match = name.indexOf(input) === 0;              var contact = el.closest(".h-card");              if(match) {                  contact.show();              } else {                  contact.hide();              }         });      }

(引用一個分離的、具名的函數,比起定義一個匿名函數來說,通常會使得回呼函數更便於管理。)

請注意,這個事件處理函數依賴於特定的DOM環境,它取決於觸發這個事件的元素(它的執行內容會映射到this指標上)。我們將從這個元素開始遍曆DOM結構,以訪問連絡人清單,並找出所有包含名稱的元素(這是由微格式的語義所定義的)。如果某個名稱的開頭部分與當前輸入的內容不匹配,我們就再次向上遍曆,將相應的容器元素隱藏起來,否則的話,就要保證該元素依然可見。

查看本欄目更多精彩內容:http://www.bianceng.cnhttp://www.bianceng.cn/webkf/script/

聯繫我們

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