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

首頁 > 編程 > JavaScript > 正文

基于RequireJS和JQuery的模塊化編程――常見問題全面解析

2019-11-20 10:15:46
字體:
供稿:網(wǎng)友

由于js的代碼邏輯越來越重,一個(gè)js文件可能會(huì)有上千行,十分不利于開發(fā)與維護(hù)。最近正在把邏輯很重的js拆分成模塊,在一頓糾結(jié)是使用requirejs還是seajs的時(shí)候,最終還是偏向于requirejs。畢竟官方文檔比較專業(yè)嘛...

不過即便是有完整的官方文檔,仍然遇到不少的問題,比如jquery-ui的使用。

下面就循序漸進(jìn)的講解一下我遇到的問題,以及解決的辦法。

關(guān)于AMD和CMD的理解

AMD(異步模塊定義)的典型就是requirejs,而CMD(通用模塊定義)的典型是淘寶的seajs。

他們的相同點(diǎn)是,都會(huì)異步的加載js。但是不同點(diǎn)是,require.js加載完會(huì)立即執(zhí)行;而seajs則是等到進(jìn)入主函數(shù)需要執(zhí)行時(shí)才執(zhí)行。

如果使用seajs初始的加載執(zhí)行效率會(huì)比較高,但是在使用的過程中可能會(huì)取執(zhí)行js,因此可能會(huì)出現(xiàn)卡頓,影響用戶體驗(yàn)(由于我也沒試過,要是說錯(cuò)了,別見怪)。而requirejs則是在一開始就把所有加載的js都執(zhí)行,這時(shí),如果你的模塊中有一些執(zhí)行方法,它們可能并不會(huì)按照你想的順序執(zhí)行。

因此,如果已經(jīng)習(xí)慣了異步編程,并且希望有完善的文檔推薦使用requirejs;如果是想對執(zhí)行順序有特殊要求,又方便開發(fā),那么也可以使用seajs。

如何解決requirejs中循環(huán)依賴問題

如果你定義的某個(gè)a模塊使用到了b模塊,而b模塊又使用了a模塊,那么就會(huì)拋出循環(huán)依賴的異常。

比如,我這里寫了一個(gè)循環(huán)依賴的例子。

主頁面:

<!DOCTYPE html><html><head></head><body><script data-main="test.js" src="lib/require.js"></script></body></html>

主方法:

requirejs.config({  baseUrl: './'});requirejs(['js/a'],function (a){  console.log("in test");  a.testfromb();});

a.js模塊中,atest()方法提供b調(diào)用、testfromb()方法調(diào)用b的方法

define(function(require){  var b = require("js/b");  console.log("in a");  return {    atest:function(){      console.log("test in a");    },    testfromb:function(){      console.log("testfromb in a");      b.btest();    }  }});

b模塊中,調(diào)用了a的方法。

define(function(require){  var a = require("js/a");  console.log("in b");  return {    btest:function(){      console.log("test in b");      a.atest();    }  }});

這樣相當(dāng)于a調(diào)用了b的方法,但是b的方法依賴于a的方法,這就造成了循環(huán)依賴。瀏覽器會(huì)提示錯(cuò)誤:

Uncaught Error: Module name "js/a" has not been loaded yet for context: _

按照官方文檔的說法,這種屬于設(shè)計(jì)的問題,應(yīng)該盡量避免。那么如果避免不了該怎么辦呢?可以這樣修改b模塊:

define(function(require){  // var a = require("js/a");  console.log("in b");  return {    btest:function(){      console.log("test in b");      require("js/a").atest();    }  }});

這里是等到執(zhí)行atest()方法時(shí),才加載a模塊。這時(shí),a模塊很顯然已經(jīng)加載完了 ??梢钥吹捷敵龅男畔ⅲ?/p>

in ba.js:3 in atest.js:6 in testa.js:9 testfromb in ab.js:6 test in ba.js:6 test in a

同樣的方式,修改a可能就不好使了。這時(shí)因?yàn)槟K加載的順序是從b開始的。

關(guān)于循環(huán)依賴的源碼可以參考云盤

如何在requirejs中使用jquery

如果想要使用jquery比較簡單,直接在main.js中添加對應(yīng)的依賴即可:

requirejs.config({  baseUrl: './',  paths:{    'jquery':'lib/jquery'  }});requirejs(['jquery'],function ($){  $('#test').html('test');});
如何在requirejs中使用jquery插件對于jquery的插件,比較常見的做法都是傳入一個(gè)jquery的對象,在這個(gè)jquery對象的基礎(chǔ)上添加插件對應(yīng)的方法。首先需要添加jquery插件的依賴,這里用兩個(gè)插件舉例子――jquery-ui和jquery-datatables
requirejs.config({  baseUrl: './',  paths:{    'jquery':'lib/jquery',    'jquery-ui':'lib/jquery-ui',    'jquery-dataTables':'lib/jquery.dataTables'  },  shim:{    'jquery-ui':['jquery'],    'jquery-dataTables':['jquery']  }});requirejs(['jquery','jquery-ui','jquery-dataTables'],function ($){  ....});
由于jquery插件都需要依賴于jquery,因此可以在shim中指定依賴關(guān)系。除了上面這種使用方法,也可以使用commonJS風(fēng)格的調(diào)用:
define(function(require){  var $ = require('jquery');  require('jquery-ui');  require('jquery-dataTables');      //下面都是測試,可以忽略  var _test = $('#test');  _test.selectmenu({    width : 180,    change : function(event, ui) {      console.log('change');    }  });  return {    test:function(){      //測試jquery-ui      _test.append($('<option>test1</option><option>test1</option>'));      _test.selectmenu("refresh");      //測試jquery-datatables      var _table = $('table');      _table.dataTable();    }  }});

不過,執(zhí)行上面的代碼,會(huì)報(bào)一個(gè)異常:

Uncaught TypeError: _table.dataTable is not a function

這是因?yàn)椋琩ataTables并不是一個(gè)require風(fēng)格的模塊,因此直接這樣引入,并不會(huì)執(zhí)行它內(nèi)部的匿名函數(shù)。可以修改它的匿名函數(shù),傳入$對象,在最后一行:

*/  return $.fn.dataTable;//}));原來是這樣}($)));//這里增加執(zhí)行這個(gè)匿名函數(shù),并且傳入$對象。}(window, document));

這也是在網(wǎng)上搜的方法,原理奈何經(jīng)驗(yàn)不足....

樣例代碼可以參考云盤,由于引入的資源不是很全,所以會(huì)報(bào)錯(cuò),可以直接忽略,因?yàn)槟軋?zhí)行UI插件就表示已經(jīng)成功了。

requirejs使用jquery-ui的問題

由于requirejs加載js文件后會(huì)立即執(zhí)行,如果你的jquery ui 插件需要刷新DOM頁面,那么可能會(huì)導(dǎo)致頁面的事件失效。

比如,你的模塊在加載后,對頁面的某個(gè)元素$('#test')綁定了click事件。但是使用了某個(gè)UI插件,這個(gè)插件會(huì)重新渲染DOM元素,test對應(yīng)的click事件就失效了。

解決辦法:

•把事件綁定推遲到DOM元素渲染完后再手動(dòng)觸發(fā)綁定;
•也可以使用事件捕獲代替DOM元素的事件綁定(太麻煩了...不推薦)。

比如在DOM重構(gòu)的JS模塊中,執(zhí)行渲染的代碼下面:

require("xxx").initEvents();常見場景:

比如我在頁面中使用了jquery-steps這個(gè)UI插件,它會(huì)對頁面進(jìn)行重新渲染。這就導(dǎo)致我最開始綁定的事件都失效了....只有推遲到這個(gè)js重構(gòu)完頁面,再綁定才行。

以上這篇基于RequireJS和JQuery的模塊化編程――常見問題全面解析就是小編分享給大家的全部內(nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持武林網(wǎng)。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 马关县| 莎车县| 米泉市| 随州市| 龙陵县| 永清县| 大新县| 池州市| 清新县| 井冈山市| 成都市| 平昌县| 安国市| 荥阳市| 牡丹江市| 怀宁县| 阿合奇县| 芮城县| 育儿| 介休市| 黄梅县| 中卫市| 资源县| 天长市| 临安市| 阿图什市| 贺兰县| 加查县| 博野县| 凤翔县| 澎湖县| 沂源县| 绩溪县| 修武县| 荣昌县| 比如县| 寻乌县| 临湘市| 思南县| 文登市| 盈江县|