文章目录
- RequireJS 是什么
- 引入 RequireJS
- require()
- ()
- 模块的写法
- 完整案例
RequireJS 是什么
<script src=""></script>
<script src=""></script>
<script src=""></script>
<script src=""></script>
<script src=""></script>
<script src=""></script>
- 1
- 2
- 3
- 4
- 5
- 6
这段代码依次加载多个js文件。这种写法有很大的缺点。首先,加载的时候,浏览器会停止网页渲染,加载文件越多,网页失去响应的时间就会越长;其次,由于js文件之间存在依赖关系,因此必须严格保证加载顺序(比如上例的要在的前面),依赖性最大的模块一定要放到最后加载,当依赖关系很复杂的时候,代码的编写和维护都会变得困难。
RequireJS 解决了这两个问题
(1)实现js文件的异步加载,避免网页失去响应;
(2)管理模块之间的依赖性,便于代码的编写和维护。
引入 RequireJS
- 在html 中引入
<script type="text/javascript" data-main="js/main" src="js/lib/" defer async="true"></script>
- 1
async:属性表明这个文件需要异步加载,避免网页失去响应 (或不写 async 把它放在网页底部加载)。IE不支持这个属性,只支持defer,所以把defer也写上。
data-main:作用是,指定网页程序的主模块。在上例中,就是js目录下面的,这个文件会第一个被加载。由于默认的文件后缀名是js,所以可以把简写成main。
require()
接收两个参数
参数1:是一个数组,表示 所依赖的模块
参数2:是一个回调函数,当前面指定的模块都加载成功后,它将被调用。加载的模块会以参数形式传入该函数,从而在回调函数内部就可以使用这些模块。
假定主模块依赖jquery、underscore和backbone这三个模块,就可以这样写:
//
require(['jquery', 'underscore', 'backbone'], function ($, _, Backbone){
// some code here
});
- 1
- 2
- 3
- 4
会先异步加载 jQuery、underscore和backbone,浏览器不会失去响应,然后再运行回调函数。主模块的代码就写在回调函数中。
()
paths属性
指定各个模块的加载路径。默认情况下,假定这三个模块与在同一个目录,文件名分别为,和,然后自动加载。
shim属性,专门用来配置不兼容的模块:
exports: 输出的变量名,表明这个模块外部调用时的名称
deps数组: 表明该模块的依赖性
//
require.config({
paths: { //默认
"jquery": "",
"underscore": "",
"backbone": ""
},
shim: {
'underscore':{
exports: '_'
},
'backbone': {
exports: 'Backbone',
deps: ['underscore', 'jquery']
}
}
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
如果这些模块在其他目录,比如js/lib目录,则有两种写法。一种是 逐一指定路径 。另一种则是 直接改变基目录(baseUrl)。
require.config({ //逐一指定路径
paths: {
"jquery": "lib/",
"underscore": "lib/",
"backbone": "lib/"
}
});
require.config({ //直接改变基目录(baseUrl)
baseUrl: "js/lib",
paths: {
"jquery": "",
"underscore": "",
"backbone": ""
}
});
require.config({ //也可以直接指定它的网址
paths: {
"jquery": "/ajax/libs/jquery/1.7.2/"
}
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
模块的写法
加载的模块,采用AMD规范。也就是说,模块必须按照AMD的规定来写
具体来说,就是模块必须采用特定的 define()函数 来定义。如果一个模块不依赖其他模块,那么可以直接定义在define()函数之中。
假定现在有一个文件,它定义了一个math模块。那么,就要这样写:
//
define(function (){
var add = function (x,y){
return x+y;
};
return {
add: add
};
});
//如果这个模块还依赖其他模块,那么define()函数的第一个参数,必须是一个数组,指明该模块的依赖性。
define(['myLib'], function(myLib){
function foo(){
myLib.doSomething();
}
return {
foo : foo
};
});
//当require()函数加载上面这个模块的时候,就会先加载文件。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
加载方法如下:
//
require(['math'], function (math){
alert(math.add(1,1));
});
- 1
- 2
- 3
- 4
小案例
完整案例
下面我们可以自己封装一下弹窗,让其他 js 文件可以调用封装好的模块
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./js/" data-main="js/" defer async="true"></script>
</head>
<body>
<div class="btn" style="border: 1px solid #666;width: 60px;text-align: center;cursor: pointer;">按钮</div>
</body>
</html>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
//
require.config({ //配置路径
paths: {
"jquery": "",
"dialog": "dialog",
"other": "other"
}
});
require(['dialog','other'], function (dialog,other) { //引入 js 文件
console.log(dialog)
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
// 封装的弹窗代码
define(['jquery'], function ($) {
var dialog = {}
var callback = null
dialog.add = function () {
let _html = `
<div class="dialog-wrap" style="width: 100%;height: 100%; background-color: rgba(0, 0, 0, .6);
position: fixed;display: none;justify-content: center; align-items: center;top:0;left:0
z-index: 999;">
<div class="dialog-main" style="width: 80%;max-width:400px;background-color: #fff; border-radius: 6px;
padding: 10px;margin-top: -30px;transition: all .3s ease-out;opacity: 0;">
<div class="dialog-tit" style="text-align: center;font-weight: bold;
border-bottom: 1px solid lightgrey;
font-size: 20px;line-height: 2;color: green;">提交成功</div>
<p class="dialog-content" style="line-height: 1.6;">恭喜你提交成功,24小时内将会有工作人员联系您,请保持电话通畅</p>
<div class="dialog-btn" style="width: 80px;margin: 10px auto;padding: 4px 0;
text-align: center;background: #607D8B;
border-radius: 4px;color: #fff;cursor: pointer">确定</div>
</div>
</div>
`
$('html').append(_html)
$('.dialog-btn').click(function () {
$('.dialog-main').css({
"margin-top": '-30px',
"opacity": '0'
})
setTimeout(function(){
$('.dialog-wrap').css('display', 'none')
},200)
callback && callback()
})
}
dialog.show = function (tit, content, callbackfn) {
$('.dialog-wrap').css("display", "flex")
$('.dialog-tit').text(tit)
$('.dialog-content').text(content)
setTimeout(() => {
$('.dialog-main').css({
"margin-top": '0',
"opacity": '1'
})
}, 20);
callback = callbackfn
}
dialog.hide = function () {
$('.dialog-main').css({
"margin-top": '-30px',
"opacity": '0'
})
setTimeout(function(){
$('.dialog-wrap').css('display', 'none')
},200)
}
return dialog
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
//
define(["dialog","jquery"] ,function(dialog, $){
dialog.add()
$('.btn').click(function(){
dialog.show('标题','输入内容',function(){console.log('done')})
})
})
- 1
- 2
- 3
- 4
- 5
- 6
- 7
参考:[《Javascript模块化编程(三):的用法》——阮一峰](
/blog/2012/11/require_js.html)