一、認識RequireJSjavascript
RequireJs官網(http://requirejs.org/)的描述:html
RequireJS is a JavaScript file and module loader. It is optimized for in-browser use, but it can be used in other JavaScript environments, like Rhino and Node. Using a modular script loader like RequireJS will improve the speed and quality of your code.java
RequireJS是一個用來加載模塊的js文件,它是在瀏覽器端的一個優化設計,同時它可以在其餘js環境下使用,好比Rhino和Node,使用相似於RequireJS的js模塊加載器可以提高您的代碼執行速度和質量jquery
二、使用RequireJS數組
(1)平時咱們引用js的方式瀏覽器
index.html異步
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <script type="text/javascript" src="js/my/dr.js"></script> <title></title> </head> <body> <p>this is index.html</p> <script> console.log("dr.version: "+dr.version); </script> </body> </html>
js/my/dr.jsasync
! function(window) {
var dr = {}; dr.version = "v1.0"; window.dr = dr; }(window);
控制檯輸出
dr.version: v1.0
(2)引用requirejs的方式ide
一個簡單的例子:函數
目錄結構:
index.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <script type="text/javascript" src="js/require.js" data-main="js/main"></script> <title></title> </head> <body> <p>this is index.html</p> </body> </html>
js/my/dr.js
! function(window) {
var dr = {}; dr.version = "v1.0"; window.dr = dr; define(function() { return dr; }); }(window);
js/main.js
require.config({ baseUrl: "js", paths: { dr: "my/dr" } }) require(["dr"], function(dr) { if (dr) { console.log("dr.js is ready!");
console.log("dr.version: " + dr.version); } })
測試,控制檯輸出:
dr.js is ready!
dr.version: v1.0
一、看下index.html。
在<head>標籤中引入了require的js文件,並指明屬性 data-main="js/main.js",這個屬性至關於指明瞭RequireJs的入口,與java中的mian方法類似(這個屬性的值能夠直接寫成"js/main",require會自動去找js下的main.js文件)。
二、看下RequireJs的「入口」main.js。
require.config():配置require的基本信息。
baseUrl若是不指定的話,那默認爲main.js的文件夾路徑,即"js",咱們的代碼中寫不寫baseUrl屬性都無所謂,由於咱們與main的文件夾路徑是一致的;
path:咱們要引用的js文件和路徑,若是要引用多個js文件,追加便可,可是這裏咱們引用的js文件中必須符合AMD規範(異步模塊加載機制)才能夠,簡單的說就是必須有define()方法。
require():兩個參數,第一個是數組,裏面存放咱們要引用的js文件的名稱,與上面config方法中的paths中的名稱對應,第二個是引用完成後的回調函數,在這個函數中有個參數,這個參數值就是js文件中define()方法的返回值。
三、看下dr.js
! function(window) { var dr = {}; dr.version = "v1.0"; window.dr = dr; define(function() { return dr; }); }(window);
這個跟以前(1)平時咱們引用js的方式相比,多了一個define函數(斜體部分),這個函數返回了dr對象。這樣才符合AMD規範,咱們在main.js的require()的回調函數中才能獲得dr.version的值。
簡單的總結下:
一、在咱們須要引用的js文件中定義define()方法,返回某個對象。
二、編寫main.js方法(固然名字寫成什麼均可以,只要在index引用RequireJs文件的時候指明屬性data-main的值爲對應的main.js便可)。編寫配置文件(指定baseUrl,paths裏面存放咱們要引用的js文件,這裏js文件都是做爲module的方式被require異步加載)
三、在index.html中引入requirejs文件,指明require入口,在頁面中使用便可。
下面是我加載兩個模塊的例子(dr.js和jquery.js),很簡單,各位一眼就能看懂的。
目錄結構:
(配圖有誤,後面測試的時候將jquery文件夾修改成了jq)
按照步驟來:
一、在dr.js和jquery.js中編寫define()方法。dr.js咱們剛剛已經寫過了,這裏不改動;jquery呢?看下jquery源碼:
// Expose jQuery as an AMD module, but only for AMD loaders that // understand the issues with loading multiple versions of jQuery // in a page that all might call define(). The loader will indicate // they have special allowances for multiple jQuery versions by // specifying define.amd.jQuery = true. Register as a named module, // since jQuery can be concatenated with other files that may use define, // but not use a proper concatenation script that understands anonymous // AMD modules. A named AMD is safest and most robust way to register. // Lowercase jquery is used because AMD module names are derived from // file names, and jQuery is normally delivered in a lowercase file name. // Do this after creating the global so that if an AMD module wants to call // noConflict to hide this version of jQuery, it will work. if ( typeof define === "function" && define.amd && define.amd.jQuery ) { define( "jquery", [], function () { return jQuery; } ); }
已經看到jquery已經寫好了,將jQuery作一個異步加載的module實現。
二、編寫main.js,在paths中添加jquery的配置,名稱爲「jquery」,路徑是「jq/jquery」,表明着引入"js/jq/"下的jquery.js文件,注意:這裏的路徑不能寫後綴".js";在require中添加jquery的模塊。
require.config({ baseUrl: "js", paths: { jquery: "jq/jquery", dr: "my/dr" } }) require(["jquery", "dr"], function($, dr) { if ($) { console.info("jquery is ready!"); console.log("jquery version: "+$().jquery); } if (dr) { console.info("dr.js is ready!"); console.log("dr.version: " + dr.version) } })
三、index.html,增長一個按鈕,用於測試jquery和dr是否正確引入
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <script type="text/javascript" src="js/require.js" data-main="js/main.js" async="async" defer="defer"></script> <title></title> </head> <body> <p>this is index.html</p> <button onclick="getVersion();">獲取版本</button> <script> function getVersion() { console.log("index-->jquery version: " + $().jquery); console.log("index-->dr version: " + dr.version); } </script> </body> </html>
測試:
jquery is ready!
jquery version: 1.9.1
dr.js is ready!
dr.version: v1.0
//點擊button按鈕時候控制檯輸出
index-->jquery version: 1.9.1
index-->dr version: v1.0
這裏存在一個問題,很大的問題:若是咱們把getVersion()的function包裝去掉,直接在script中寫
console.log("index-->jquery version: " + $().jquery);
或者
console.log("index-->dr version: " + dr.version);
會發生什麼呢?
Uncaught ReferenceError: $ is not defined
jquery is ready!
jquery version: 1.9.1
dr.js is ready!
dr.version: v1.0
或者
Uncaught ReferenceError: dr is not defined
jquery is ready!
jquery version: 1.9.1
dr.js is ready!
dr.version: v1.0
問題的根源在於,在requirejs異步加載jquery和dr的時候,index.html的文檔流已經讀完了,因此發生了錯誤,以後又異步獲取到了require加載jquery和dr完成的回調函數。