搜尋
首頁web前端js教程基於RequireJS和JQuery的模組化程式設計-常見問題全面解析_javascript技巧

由於js的程式碼邏輯越來越重,一個js檔案可能會有上千行,十分不利於開發與維護。最近把邏輯很重的js分割成模組,在一頓糾結是使用requirejs還是seajs的時候,最後還是偏向requirejs。畢竟官方文件比較專業嘛...

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

以下就循序漸進的講解一下我遇到的問題,以及解決的辦法。

關於AMD和CMD的理解

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

他們的相同點是,都會異步的載入js。但不同點是,require.js載入完會立即執行;而seajs則是等到進入主函數需要執行時才執行。

如果使用seajs初始的載入執行效率會比較高,但是在使用的過程中可能會取執行js,因此可能會出現卡頓,影響使用者體驗(由於我也沒試過,要是說錯了,別見怪)。而requirejs則是在一開始就把所有載入的js都執行,這時,如果你的模組中有一些執行方法,它們可能不會按照你想的順序執行。

因此,如果已經習慣了非同步編程,並且希望有完善的文檔推薦使用requirejs;如果是想對執行順序有特殊要求,又方便開發,那麼也可以使用seajs。

如何解決requirejs中循環依賴問題

如果你定義的某個a模組使用到了b模組,而b模組又使用了a模組,那麼就會拋出循環依賴的異常。

比如,我這裡寫了一個循環依賴的例子。

主頁:

<!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呼叫、testfromb()方法呼叫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模組中,呼叫了a的方法。

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

這樣相當於a呼叫了b的方法,但是b的方法依賴a的方法,這就造成了循環相依性。瀏覽器會提示錯誤:

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

依照官方文件的說法,這種屬於設計的問題,應該盡量避免。那如果避免不了該怎麼辦呢?可以這樣修改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();
    }
  }
});

這裡是等到執行atest()方法時,才載入a模組。這時,a模組很顯然已經加載完了 。可以看到輸出的資訊:

in b
a.js:3 in a
test.js:6 in test
a.js:9 testfromb in a
b.js:6 test in b
a.js:6 test in a

同樣的方式,修改a可能就不好使了。這時因為模組載入的順序是從b開始的。

關於循環依賴的源碼可以參考雲盤

如何在requirejs中使用jquery

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

requirejs.config({
  baseUrl: './',
  paths:{
    'jquery':'lib/jquery'
  }
});

requirejs(['jquery'],
function ($){
  $('#test').html('test');
});
如何在requirejs中使用jquery插件

对于jquery的插件,比较常见的做法都是传入一个jquery的对象,在这个jquery对象的基础上添加插件对应的方法。

首先需要添加jquery插件的依赖,这里用两个插件举例子——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中指定依赖关系。
除了上面这种使用方法,也可以使用commonJS风格的调用:

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();
    }
  }
});

不過,執行上面的程式碼,會報一個異常:

Uncaught TypeError: _table.dataTable is not a function

這是因為,dataTables並不是一個require風格的模組,因此直接這樣引入,並不會執行它內部的匿名函數。可以修改它的匿名函數,傳入$對象,在最後一行:

*/

  return $.fn.dataTable;
//}));原来是这样
}($)));//这里增加执行这个匿名函数,并且传入$对象。

}(window, document));

這也是在網路上搜尋的方法,原理奈何經驗不足....

範例程式碼可以參考雲盤,由於引入的資源不是很全,所以會報錯,可以直接忽略,因為能執行UI插件就表示已經成功了。

requirejs使用jquery-ui的問題

由於requirejs載入js檔案後會立即執行,如果你的jquery ui 外掛需要刷新DOM頁面,那麼可能會導致頁面的事件失效。

例如,你的模組在載入後,對頁面的某個元素$('#test')綁定了click事件。但是使用了某個UI插件,這個插件會重新渲染DOM元素,test對應的click事件就失效了。

解決方法:

•把事件綁定延後到DOM元素渲染完再手動觸發綁定;
•也可以使用事件捕獲來代替DOM元素的事件綁定(太麻煩了...不建議)。

例如在DOM重構的JS模組中,執行渲染的程式碼下面:

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

例如我在頁面中使用了jquery-steps這個UI插件,它會對頁面進行重新渲染。這就導致我最開始綁定的事件都失效了....只有推遲到這個js重構完頁面,再綁定才行。

以上這篇基於RequireJS和JQuery的模組化程式設計-常見問題全面解析就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持腳本之家。

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
jquery实现多少秒后隐藏图片jquery实现多少秒后隐藏图片Apr 20, 2022 pm 05:33 PM

实现方法:1、用“$("img").delay(毫秒数).fadeOut()”语句,delay()设置延迟秒数;2、用“setTimeout(function(){ $("img").hide(); },毫秒值);”语句,通过定时器来延迟。

axios与jquery的区别是什么axios与jquery的区别是什么Apr 20, 2022 pm 06:18 PM

区别:1、axios是一个异步请求框架,用于封装底层的XMLHttpRequest,而jquery是一个JavaScript库,只是顺便封装了dom操作;2、axios是基于承诺对象的,可以用承诺对象中的方法,而jquery不基于承诺对象。

jquery怎么修改min-height样式jquery怎么修改min-height样式Apr 20, 2022 pm 12:19 PM

修改方法:1、用css()设置新样式,语法“$(元素).css("min-height","新值")”;2、用attr(),通过设置style属性来添加新样式,语法“$(元素).attr("style","min-height:新值")”。

jquery怎么在body中增加元素jquery怎么在body中增加元素Apr 22, 2022 am 11:13 AM

增加元素的方法:1、用append(),语法“$("body").append(新元素)”,可向body内部的末尾处增加元素;2、用prepend(),语法“$("body").prepend(新元素)”,可向body内部的开始处增加元素。

jquery中apply()方法怎么用jquery中apply()方法怎么用Apr 24, 2022 pm 05:35 PM

在jquery中,apply()方法用于改变this指向,使用另一个对象替换当前对象,是应用某一对象的一个方法,语法为“apply(thisobj,[argarray])”;参数argarray表示的是以数组的形式进行传递。

jquery怎么删除div内所有子元素jquery怎么删除div内所有子元素Apr 21, 2022 pm 07:08 PM

删除方法:1、用empty(),语法“$("div").empty();”,可删除所有子节点和内容;2、用children()和remove(),语法“$("div").children().remove();”,只删除子元素,不删除内容。

jquery怎么去掉只读属性jquery怎么去掉只读属性Apr 20, 2022 pm 07:55 PM

去掉方法:1、用“$(selector).removeAttr("readonly")”语句删除readonly属性;2、用“$(selector).attr("readonly",false)”将readonly属性的值设置为false。

jquery on()有几个参数jquery on()有几个参数Apr 21, 2022 am 11:29 AM

on()方法有4个参数:1、第一个参数不可省略,规定要从被选元素添加的一个或多个事件或命名空间;2、第二个参数可省略,规定元素的事件处理程序;3、第三个参数可省略,规定传递到函数的额外数据;4、第四个参数可省略,规定当事件发生时运行的函数。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

將Eclipse與SAP NetWeaver應用伺服器整合。

VSCode Windows 64位元 下載

VSCode Windows 64位元 下載

微軟推出的免費、功能強大的一款IDE編輯器

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。