国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

JavaScript模塊化之使用requireJS按需加載

2019-11-19 16:51:15
字體:
供稿:網(wǎng)友

模塊加載器的概念可能稍微接觸過前端開發(fā)的童鞋都不會陌生,通過模塊加載器可以有效的解決這些問題:

  1. JS文件的依賴關(guān)系。
  2. 通過異步加載優(yōu)化script標(biāo)簽引起的阻塞問題
  3. 可以簡單的以文件為單位將功能模塊化并實現(xiàn)復(fù)用

主流的JS模塊加載器有requireJS,SeaJS等,加載器之間可能會因為遵循的規(guī)范不同有微妙的差別,從純用戶的角度出發(fā),之所以選requireJS而不是SeaJS主要是因為:

功能實現(xiàn)上兩者相差無幾,沒有明顯的性能差異或重大問題。

文檔豐富程度上,requireJS遠(yuǎn)遠(yuǎn)好于SeaJS,就拿最簡單的加載jQuery和jQuery插件這回事,雖然兩者的實現(xiàn)方法相差無幾,但requireJS就有可以直接拿來用的Demo,SeaJS還要讀文檔自己慢慢折騰。一些問題的解決上,requireJS為關(guān)鍵詞也更容易找到答案。

requireJS 加載jQuery + jQuery插件

可能對于一般Web App來說,引入jQuery及相關(guān)插件的概率是最大的,requireJS也親切的給出了相應(yīng)的解決方案及動態(tài)加載jQuery及插件的文檔及實例代碼

在最新的jQuery1.9.X中,jQuery已經(jīng)在最后直接將自己注冊為一個AMD模塊,即是說可以直接被requireJS作為模塊加載。如果是加載舊版的jQuery有兩種方法:

1. 讓jQuery先于requireJS加載

2. 對jQuery代碼稍做一點處理,在jQuery代碼包裹一句:

define(["jquery"], function($) {   // $ is guaranteed to be jQuery now */ }); 

requireJS的示例中,直接將requireJS與jQuery合并為一個文件,如果是采用jQuery作為核心庫的話推薦這種做法。

同樣對于jQuery插件來說也有兩種方法

1. 在插件外包裹代碼

define(["jquery"], function($){    // Put here the plugin code. }); 

2. 在使用reuqireJS代碼加載前注冊插件(比如在main.js)中

requirejs.config({   "shim": {     "jquery-cookie" : ["jquery"]   } }); 

requireJS加載第三方類庫

在實例的App中還用到了jQuery以外的第三方類庫,如果類庫不是一個標(biāo)準(zhǔn)的AMD模塊而又不想更改這些類庫的代碼,同樣需要提前進(jìn)行定義:

require.config({    paths: {       'underscore': 'vendor/underscore'    },    shim: {      underscore: {        exports: '_'      }    } }); 

CSS文件的模塊化處理

在requireJS中,模塊的概念僅限于JS文件,如果需要加載圖片、JSON等非JS文件,requireJS實現(xiàn)了一系列加載插件。

但是遺憾的是requireJS官方?jīng)]有對CSS進(jìn)行模塊化處理,而我們在實際項目中卻往往能遇到一些場景,比如一個輪播的圖片展示欄,比如高級編輯器等等。幾乎所有的富UI組件都會由JS與CSS兩部分構(gòu)成,而CSS之間也存在著模塊的概念以及依賴關(guān)系。

為了更好的與requireJS整合,這里采用require-css來解決CSS的模塊化與依賴問題。

require-css是一個requireJS插件,下載后將css.js與normalize.js放于main.js同級即可默認(rèn)被加載,比如在我們的項目中需要加載jQuery Mobile的css文件,那么可以直接這樣調(diào)用:

require(['jquery', 'css!../css/jquery.mobile-1.3.0.min.css'], function($) { }); 

不過由于這個CSS本質(zhì)上是屬于jQuery Mobile模塊的一部分,更好的做法是將這個CSS文件的定義放在jQuery Mobile的依賴關(guān)系中,最終我們的requireJS定義部分為:

require.config({    paths: {       'jquerymobile': 'vendor/jquery.mobile-1.3.0',       'jstorage' : 'vendor/jstorage',       'underscore': 'vendor/underscore'    },    shim: {      jquerymobile : {       deps: [         'css!../css/jquery.mobile-1.3.0.min.css'       ]      },      underscore: {        exports: '_'      }    } }); 

在使用模塊時,只需要:

require(['jquery', 'underscore', 'jquerymobile', 'jstorage'], function($, _) { }); 

jQuery Mobile的CSS文件就會被自動加載,這樣CSS與JS就被整合為一個模塊了。同理其他有復(fù)雜依賴關(guān)系的模塊也可以做類似處理,requireJS會解決依賴關(guān)系的邏輯。

數(shù)據(jù)源的加載與等待

Web App一般都會動態(tài)加載后端的數(shù)據(jù),數(shù)據(jù)格式一般可以是JSON、JSONP也可以直接是一個JS變量。這里以JS變量為例:

var restaurants = [   {     "name": "KFC"   },   {     "name": "7-11"   },   {     "name": "成都小吃"   } ] 

載入這段數(shù)據(jù):

$.getScript('data/restaurants.json', function(e){   var data = window.restaurants;   alert(data[0].name); //KFC }); 

單一的數(shù)據(jù)源確實很簡單,但是往往一個應(yīng)用中會有多個數(shù)據(jù)源,比如在這個實例App中UI就需要載入用戶信息、餐廳信息、訂餐信息三種數(shù)據(jù)后才能工作。如果僅僅靠多層嵌套回調(diào)函數(shù)的話,可能代碼的耦合就非常重了。

為了解決多個數(shù)據(jù)加載的問題,我習(xí)慣的解決方法是構(gòu)造一個dataReady事件響應(yīng)機(jī)制。

var foodOrder = {    //數(shù)據(jù)載入后要執(zhí)行的函數(shù)暫存在這里   dataReadyFunc : []    //數(shù)據(jù)源URL及載入狀態(tài)   , dataSource : [     { url : 'data/restaurants.json', ready : false, data : null },     { url : 'data/users.json', ready : false, data : null },     { url : 'data/foods.json', ready : false, data : null }   ]    //檢查數(shù)據(jù)源是否全部載入完畢   , isReady : function(){     var isReady = true;     for(var key in this.dataSource){       if(this.dataSource[key].ready !== true){         isReady = false;       }     }     return isReady;   }    //數(shù)據(jù)源全部加載完畢,則逐一運行dataReadyFunc中存放的函數(shù)   , callReady : function(){     if(true === this.isReady()){       for(var key in this.dataReadyFunc){         this.dataReadyFunc[key]();       }     }   }    //供外部調(diào)用,會將外部輸入的函數(shù)暫存在dataReadyFunc中   , dataReady : function(func){     if (typeof func !== 'function') {       return false;     }     this.dataReadyFunc.push(func);   }    , init : function(){     var self = this;     var _initElement = function(key, url){       $.getScript(url, function(e){         //每次載入數(shù)據(jù)后,將數(shù)據(jù)存放于dataSource中,將ready狀態(tài)置為true,并調(diào)用callReady         self.dataSource[key].data = window[key];         self.dataSource[key].ready = true;         self.callReady();       });     }     for(var key in this.dataSource){       _initElement(key, this.dataSource[key].url);     }   } } 

用法為:

foodOrder.dataReady(function(){   alert(1);   }); foodOrder.init(); 

dataReady內(nèi)的alert將會在所有數(shù)據(jù)載入完畢后開始執(zhí)行。

這段處理的邏輯并不復(fù)雜,將所有要執(zhí)行的方法通過dataReady暫存起來,等待數(shù)據(jù)全部加載完畢后再執(zhí)行,更加復(fù)雜的場景此方法仍然通用。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持武林網(wǎng)。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 汪清县| 罗田县| 宣威市| 屯门区| 右玉县| 滨州市| 凤冈县| 安陆市| 科尔| 祁阳县| 连平县| 广宁县| 东方市| 松滋市| 屯门区| 深州市| 南通市| 库车县| 乌审旗| 彝良县| 平顶山市| 北京市| 绥棱县| 东台市| 双鸭山市| 吉林省| 六枝特区| 那曲县| 施甸县| 什邡市| 仁化县| 海晏县| 嘉鱼县| 简阳市| 太湖县| 彩票| 永春县| 隆子县| 合山市| 莱阳市| 辽宁省|