基於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的模組化程式設計-常見問題全面解析就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持腳本之家。

熱AI工具

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

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

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

jQuery引用方法詳解:快速上手指南jQuery是一個受歡迎的JavaScript庫,被廣泛用於網站開發中,它簡化了JavaScript編程,並為開發者提供了豐富的功能和特性。本文將詳細介紹jQuery的引用方法,並提供具體的程式碼範例,幫助讀者快速上手。引入jQuery首先,我們需要在HTML檔案中引入jQuery函式庫。可以透過CDN連結的方式引入,也可以下載

jQuery中如何使用PUT請求方式?在jQuery中,發送PUT請求的方法與發送其他類型的請求類似,但需要注意一些細節和參數設定。 PUT請求通常用於更新資源,例如更新資料庫中的資料或更新伺服器上的檔案。以下是在jQuery中使用PUT請求方式的具體程式碼範例。首先,確保引入了jQuery庫文件,然後可以透過以下方式發送PUT請求:$.ajax({u

jQuery是一款廣泛應用於前端開發的快速、小巧、功能豐富的JavaScript庫。自2006年發布以來,jQuery已成為眾多開發者的首選工具之一,但在實際應用中,它也不乏一些優點和缺點。本文將深度剖析jQuery的優勢與劣勢,並結合具體的程式碼範例進行說明。優點:1.簡潔的語法jQuery的語法設計簡潔明了,可以大幅提升程式碼的可讀性和編寫效率。比如,

jQuery如何移除元素的height屬性?在前端開發中,經常會遇到需要操作元素的高度屬性的需求。有時候,我們可能需要動態改變元素的高度,而有時候又需要移除元素的高度屬性。本文將介紹如何使用jQuery來移除元素的高度屬性,並提供具體的程式碼範例。在使用jQuery操作高度屬性之前,我們首先需要了解CSS中的height屬性。 height屬性用於設定元素的高度

標題:jQuery小技巧:快速修改頁面所有a標籤的文字在網頁開發中,我們經常需要對頁面中的元素進行修改和操作。使用jQuery時,有時候需要一次修改頁面中所有a標籤的文字內容,這樣可以節省時間和精力。以下將介紹如何使用jQuery快速修改頁面所有a標籤的文本,同時給出具體的程式碼範例。首先,我們需要引入jQuery庫文件,確保在頁面中引入了以下程式碼:<

標題:使用jQuery修改所有a標籤的文字內容jQuery是一款受歡迎的JavaScript庫,被廣泛用於處理DOM操作。在網頁開發中,經常會遇到需要修改頁面上連結標籤(a標籤)的文字內容的需求。本文將介紹如何使用jQuery來實現這個目標,並提供具體的程式碼範例。首先,我們需要在頁面中引入jQuery庫。在HTML檔案中加入以下程式碼:

jQuery是一種流行的JavaScript庫,被廣泛用於處理網頁中的DOM操作和事件處理。在jQuery中,eq()方法是用來選擇指定索引位置的元素的方法,具體使用方法和應用場景如下。在jQuery中,eq()方法選擇指定索引位置的元素。索引位置從0開始計數,即第一個元素的索引是0,第二個元素的索引是1,依此類推。 eq()方法的語法如下:$("s

如何判斷jQuery元素是否具有特定屬性?在使用jQuery操作DOM元素時,常會遇到需要判斷元素是否具有某個特定屬性的情況。在這種情況下,我們可以藉助jQuery提供的方法來輕鬆實現這項功能。以下將介紹兩種常用的方法來判斷一個jQuery元素是否具有特定屬性,並附上具體的程式碼範例。方法一:使用attr()方法和typeof運算子//判斷元素是否具有特定屬
