1.ajax
var xhr = new XMLHttpRequest(); // 声明一个请求对象
// 前端设置是否带 cookie
xhr.withCredentials = true;
xhr.open(‘GET’, ‘xxxx’);
//xhr.open(‘post’, ‘http://www.domain2.com:8080/login’, true);
// 如何设置请求头? xhr.setRequestHeader(header, value);
xhr.setRequestHeader(‘Content-Type’, ‘application/json’);
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){// readyState 4 代表已向服务器发送请求
if(xhr.status === 200){// status 200 代表服务器返回成功
console.log(xhr.responseText); // 这是返回的文本
} else{
console.log(“Error: “+ xhr.status); // 连接失败的时候抛出错误
}
}
}
xhr.send(null);
//xhr.send(‘user=admin’);
// get 方法 send null(亦或者不传, 则直接是传递 header) ,post 的 send 则是传递值
2.jsonp
1.)原生实现:
<script>
var script = document.createElement(‘script’);
script.type = ‘text/javascript’;
// 传参并指定回调执行函数为 onBack
script.src = ‘http://www.domain2.com:8080/login?user=admin&callback=onBack’;
document.head.appendChild(script);
// 回调执行函数
function onBack(res) {
alert(JSON.stringify(res));
}
</script>
服务端返回如下(返回时即执行全局函数):
onBack({“status”: true, “user”: “admin”})
2.)jquery ajax:
$.ajax({
url: ‘http://www.domain2.com:8080/login’,
type: ‘get’,
dataType: ‘jsonp’, // 请求方式为 jsonp
jsonpCallback: “onBack”, // 自定义回调函数名
data: {}
});
3.)vue.js:
this.$http.jsonp(‘http://www.domain2.com:8080/login’, {
params: {},
jsonp: ‘onBack’
}).then((res) => {
console.log(res);
})
4.)npm 包 jsonp:
npm install jsonp –save
import originJSONP from ‘jsonp’ // 引入 jsonp
// 进行封装并 export
export default function jsonp(url,data,option) {
url += (url.indexOf(‘?’)<0? ‘?’ : ‘&’)+param(data)
return new Promise((resolve,reject)=>{
originJSONP(url,option,(err,data)=>{
if(!err){
resolve(data)
}else{
reject(err)
}
})
})
}
// 对 data 进行处理,并 encodeURIComponent()进行转码。
function param(data) {
let url = ”
for(var k in data) {
let value = data[k] !== undefined? data[k] : ”
url += ‘&’ + k + ‘=’ + encodeURIComponent(value)
}
return url ? url.substring(1) : ”
}
本节参考文章:vue 项目中 jsonp 跨域获取 qq 音乐首页推荐
3. 实现一个简单的 Promise
Promise 对象调用
let p =new Promise(function(resolve, reject){
if(/* 异步操作成功 */){
resolve(data)
}else{
reject(err)
}
})
p.then((res)=>{
console.log(res)
},(err)=>{
console.log(err)
})
实现一个简单的 Promise
function Promise(fn){
var status = ‘pending’
function successNotify(){
status = ‘fulfilled’// 状态变为 fulfilled
toDoThen.apply(undefined, arguments)// 执行回调
}
function failNotify(){
status = ‘rejected’// 状态变为 rejected
toDoThen.apply(undefined, arguments)// 执行回调
}
function toDoThen(){
setTimeout(()=>{ // 保证回调是异步执行的
if(status === ‘fulfilled’){
for(let i =0; i< successArray.length;i ++) {
successArray[i].apply(undefined, arguments)// 执行 then 里面的回掉函数
}
}else if(status === ‘rejected’){
for(let i =0; i< failArray.length;i ++) {
failArray[i].apply(undefined, arguments)// 执行 then 里面的回掉函数
}
}
})
}
var successArray = []
var failArray = []
fn.call(undefined, successNotify, failNotify)
return {
then: function(successFn, failFn){
successArray.push(successFn)
failArray.push(failFn)
return undefined // 此处应该返回一个 Promise
}
}
}
解题思路:Promise 中的 resolve 和 reject 用于改变 Promise 的状态和传参,then 中的参数必须是作为回调执行的函数。因此,当 Promise 改变状态之后会调用回调函数,根据状态的不同选择需要执行的回调函数。
本节参考文章:面向面试题和实际使用谈 promise
示例 2
const PENDING = “pending”; // 等待
const FULFILLED = “fulfilled”; // 已完成
const REJECTED = “rejected”; // 已拒绝
function Promise(executor) {
let self = this;
self.status = PENDING;
self.value;
self.reason;
function resolve(value) {
if (self.status === PENDING) {
self.status = FULFILLED;
self.value = value;
}
}
function reject(reason) {
if (self.status === PENDING) {
self.status = REJECTED;
self.reason = reason;
}
}
try {// 规范提到,执行器抛异常会 reject
executor(resolve, reject);
} catch(e) {
reject(e)
}
}
// then 方法实现
Promise.prototype.then = function (onFulfilled, onRjected) {
let self = this;
/**
* onFulfilled 和 onRejected 都是可选参数。
* 如果 onFulfilled 不是函数,其必须被忽略
* 如果 onRejected 不是函数,其必须被忽略
*/
onFulfilled = typeof onFulfilled === ‘function’ ? onFulfilled : function(value) {
return value;
};
onRjected = typeof onRjected === ‘function’ ? onRjected : function(reason) {
throw reason;
}
if (self.status === FULFILLED) {
onFulfilled(self.value);
}
if (self.status === REJECTED) {
onRjected(self.reason);
}
}
本节参考文章:Javascript Promise 学习过程总结
4. 闭包
var fn = function() {
var divs = document.querySelectorAll(‘div’);
for (var i = 0; i < 3; i++) {
divs[i].onclick = (function(i) {
return function() {
alert(i);
};
})(i);
}
};
fn();
或者如下的写法:
var fn = function() {
var divs = document.querySelectorAll(‘div’);
for (var i = 0; i < 3; i++) {
(function(i) {
divs[i].onclick = function() {
alert(i);
};
})(i);
}
};
fn();
for (var i = 0; i < 3; i++) {
setTimeout((function(i) {
return function() {
console.log(i);
};
})(i), 0);
console.log(i);
}
5. 事件代理
事件代理(Event Delegation),又称之为事件委托。是 JavaScript 中常用绑定事件的常用技巧。“事件代理”即是把原本需要绑定的事件委托给父元素,让父元素担当事件监听的职务。事件代理的原理是 DOM 元素的事件冒泡。
减少事件注册, 节省内存占用, 提高性能
可以实现当新增子对象时无需再次对其绑定
<div class=”wrap” id=”wrap”>
<div class=”btn” data-type=”btn” data-feat=”add”> 添加 </div>
<div class=”btn” data-type=”btn” data-feat=”delete”> 绘画 </div>
<div class=”btn” data-type=”btn” data-feat=”delete”> 散步 </div>
<div class=”btn” data-type=”btn” data-feat=”delete”> 静坐 </div>
</div>
<script type=”text/javascript”>
var n = 0
document.getElementById(‘wrap’).addEventListener(‘click’, function(e) {
var target = e.target;
var type = target.dataset.type;
var feat = target.dataset.feat;
if (type == ‘btn’) {
switch (feat) {
case ‘add’:
this.innerHTML += `<div class=”btn” data-type=”btn” data-feat=”delete”> 静坐 ${n}</div>`
n++
return;
case ‘delete’:
target.parentNode.removeChild(target);
return;
}
}
}, false);
</script>
6. 封装 dom 查询(面向对象)
function Elem(id){
this.elem = document.getElementById(id)
}
Elem.prototype.html = function(val){
var elem = this.elem
if(val) {
elem.innerHTML = val
return this // 链式
} else {
return elem.innerHTML
}
}
Elem.prototype.on = function(type,fn){
var elem = this.elem
elem.addEventListener(type, fn)
return this // 链式
}
// 调用
var div = new Elem(‘id’)
div.html(‘<p>hello</p>’).on(‘click’,function(){
console.log(‘suceess’)
})
7.DOM 劫持
function nodeToFragment (node) {
var flag = document.createDocumentFragment();
var child;
// 首先,所有表达式必然会返回一个值,赋值表达式亦不例外
// 理解了上面这一点,就能理解 while (child = node.firstChild) 这种用法
// 其次,appendChild 调用以后 child 会从原来 DOM 中移除
// 所以,第二次循环时,node.firstChild 已经不再是之前的第一个子元素了
while (child = node.firstChild) {
flag.appendChild(child); // 将子节点劫持到文档片段中
}
return flag
}
8. 添加 calssName
// 为元素添加类名
export function addClass(el, className) {
// 先判断一下元素是否含有需要添加的类名,有则直接 return
if(hasClass(el, className)) {
return
}
// 把该元素含有的类名以空格分割
let newClass = el.className.split(‘ ‘)
// 把需要的类名 push 进来
newClass.push(className)
// 最后以空格拼接
el.className = newClass.join(‘ ‘)
}
// 判断是否有要查看的 className,有则返回 true,否则返回 false
export function hasClass(el, className) {
let reg = new RegExp(‘(^|\\s)’ + className + ‘(\\s|$)’)
return reg.test(el.className)
}
9. 自动添加游览器前缀
let elementStyle = document.createElement(‘div’).style
// 主流浏览器内核
let vendor = (() => {
let transfromNames = {
webkit: ‘webkitTransform’,
Moz: ‘MozTransform’,
ms: ‘msTransform’,
O: ‘OTransform’,
standard: ‘transform’
}
for(let key in transfromNames) {
if(elementStyle[transfromNames[key]] !== undefined) {
return key
}
}
return false
})()
// 添加样式的浏览器前缀
export function prefixStyle(style) {
if(vendor === false) {
return false
}
if(vendor === ‘standard’) {
return style
}
return vendor + style.charAt(0).toUpperCase() + style.substr(1)
}
10. 图片懒加载
定义:延迟加载也称为惰性加载,即在长网页中延迟加载图像。用户滚动到它们之前,视口外的图像不会加载。这与图像预加载相反,在长网页上使用延迟加载将使网页加载更快。在某些情况下,它还可以帮助减少服务器负载。
<!DOCTYPE html>
<html lang=”en”>
<head>
<meta charset=”UTF-8″>
<title>Lazyload 1</title>
<style>
img {
display: block;
margin-bottom: 50px;
height: 200px;
}
</style>
</head>
<body>
<img src=”images/loading.gif” data-src=”images/1.png”>
<img src=”images/loading.gif” data-src=”images/2.png”>
<img src=”images/loading.gif” data-src=”images/3.png”>
<img src=”images/loading.gif” data-src=”images/4.png”>
<img src=”images/loading.gif” data-src=”images/5.png”>
<img src=”images/loading.gif” data-src=”images/6.png”>
<img src=”images/loading.gif” data-src=”images/7.png”>
<img src=”images/loading.gif” data-src=”images/8.png”>
<img src=”images/loading.gif” data-src=”images/9.png”>
<img src=”images/loading.gif” data-src=”images/10.png”>
<img src=”images/loading.gif” data-src=”images/11.png”>
<img src=”images/loading.gif” data-src=”images/12.png”>
<!– <script>
var num = document.getElementsByTagName(‘img’).length;
var img = document.getElementsByTagName(“img”);
var n = 0; // 存储图片加载到的位置,避免每次都从第一张图片开始遍历
lazyload(); // 页面载入完毕加载可是区域内的图片
window.onscroll = lazyload;
function lazyload() { // 监听页面滚动事件
var seeHeight = document.documentElement.clientHeight; // 可见区域高度
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop; // 滚动条距离顶部高度
for (var i = n; i < num; i++) {
if (img[i].offsetTop < seeHeight + scrollTop) {
if (img[i].getAttribute(“src”) == “images/loading.gif”) {
img[i].src = img[i].getAttribute(“data-src”);
}
n = i + 1;
}
}
}
</script>–>
// 对比一下上下两种代码,一个变量是全局变量,一个是函数的局部作用域,
<script>
function lazyload() {
var images = document.getElementsByTagName(‘img’);
var len = images.length;
var n = 0; // 存储图片加载到的位置,避免每次都从第一张图片开始遍历
return function() {
var seeHeight = document.documentElement.clientHeight;
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
for(var i = n; i < len; i++) {
if(images[i].offsetTop < seeHeight + scrollTop) {
if(images[i].getAttribute(‘src’) === ‘images/loading.gif’) {
images[i].src = images[i].getAttribute(‘data-src’);
}
n = n + 1;
}
}
}
}
var loadImages = lazyload();
loadImages(); // 初始化首页的页面图片
window.addEventListener(‘scroll’, loadImages, false);
</script>
</body>
</html>
jQuery
<script>
var n = 0,
imgNum = $(“img”).length,
img = $(‘img’);
lazyload();
$(window).scroll(lazyload);
function lazyload(event) {
for (var i = n; i < imgNum; i++) {
if (img.eq(i).offset().top < parseInt($(window).height()) + parseInt($(window).scrollTop())) {
if (img.eq(i).attr(“src”) == “default.jpg”) {
var src = img.eq(i).attr(“data-src”);
img.eq(i).attr(“src”, src);
n = i + 1;
}
}
}
}
</script>
11.img 加载图片失败时,使用默认图片
img 标签自带 onError 属性,当图片加载失败时,触发 error 事件:<img src=”image.png” onError=’this.src=”http://ww.jpg”‘ />
jQuery 的 error 事件
$(‘img’).error(function(){
$(this).attr(‘src’,”http://ww.jpg”);
});
jQuery 的 one 绑定使用 onerror 或者 jQuery 的 error 事件时,如果默认图片也发生加载失败,则会形成死循环,最好的办法是使用 one 绑定事件,只执行一次
$(“img”).one(“error”, function(e){
$(this).attr(“src”, “http://ww.jpg”);
});
12. 图片按比例响应式缩放、裁剪
html 部分:
<div class=”zoomImage” style=”background-image:url(images/test1.jpg)”></div>
css 部分:
.zoomImage{
width:100%;
height:0;
padding-bottom: 100%;
overflow:hidden;
//padding 为百分比的时候根据他父层的宽度来进行计算
background-position: center center;
background-repeat: no-repeat;
-webkit-background-size:cover;
-moz-background-size:cover;
// 把背景图像扩展至完全覆盖背景区域
background-size:cover;
}
总结:你所需要的比例,就是 width 与 padding-bottom 的比例 用的时候,直接把.zoomImage 当成 img 标签来用就可以了。
思维扩展很多轮播的插件本来是响应式的,但可能有两个问题:1. 这个轮播图你必须要给他一个高度,但高度不是固定死的,是需要按比例的 …2. 轮播图里的图片不是需要的比例 … 所以我们可以用刚刚上面的 padding 方法拿 swiper 轮播图插件举例
优化前
优化后
本节详细:如何让图片按比例响应式缩放、并自动裁剪的 css 技巧
13. 选项卡切换
html 的结构和样式:
<style type=”text/css”>
#div1 div{
width: 200px;
height:200px;
border: 1px #000 solid;
display: none;
}
.active{
background: red;
}
</style>
<body>
<div id=”div1″>
<button class=”active”>1</button>
<button>2</button>
<button>3</button>
<div style=”display: block;”>111</div>
<div>222</div>
<div>333</div>
</div>
</body>
// 过程式的编程思想
window.onload=function(){
// 获取元素
var oParent=document.getElementById(‘div1’);
var btns=oParent.getElementsByTagName(‘button’);
var divs=oParent.getElementsByTagName(‘div’);
// 通过循环给每个 btn 添加点击事件
for (var i = 0; i < btns.length; i++) {
btns[i].index=i;// 存储当前 btn 的下标
btns[i].onclick=function(){
for (var i = 0; i < btns.length; i++) {
btns[i].className=”;
divs[i].style.display=’none’;
}
this.className=’active’;
divs[this.index].style.display=’block’;// 让对应当前 btn 的 div 显示
}
}
}
// 面向对象
window.onload = function(){
var t1=new Tab();
t1.init();
};
function Tab() {
this.btns=oParent.getElementsByTagName(‘button’);
this.divs=oParent.getElementsByTagName(‘div’);
}
Tab.prototype.init=function(){
var This=this;
for (var i = 0; i < this.btns.length; i++) {
this.btns[i].index=i;
this.btns[i].onclick=function(){
This.change(this);
}
}
}
Tab.prototype.change=function(btn) {
for (var i = 0; i < this.btns.length; i++) {
this.btns[i].className=”;
this.divs[i].style.display=’none’;
}
btn.className=’active’;
this.divs[btn.index].style.display=’block’;
};
14. 元素拖拽
#div1{
width: 100px;
height: 100px;
background: red;
position: absolute;
}
<body>
<div id=’div1′></div>
</body>
// 过程式的编程思想
window.onload=function(){
var oDiv=document.getElementById(‘div1′);
var disX=0;
var disY=0;
oDiv.onmousedown=function(ev){
var ev=ev || window.event;
disX=ev.clientX-oDiv.offsetLeft;
disY=ev.clientY-oDiv.offsetTop;
document.onmousemove=function(ev){
var ev=ev || window.event;
oDiv.style.left=ev.clientX-disX+’px’;
oDiv.style.top=ev.clientY-disY+’px’;
};
document.onmouseup=function(){
document.onmousemove=null;
document.onmouseup=null;
}
return false;
}
}
// 面向对象
window.onload = function() {
var d1 = new Drag(‘div1’);
d1.init();
};
function Drag(id) {
this.oDiv = document.getElementById(id);
this.disX = 0;
this.disY = 0;
}
Drag.prototype.init = function() {
var This = this;
this.oDiv.onmousedown = function(ev) {
var ev = ev || window.event;
This.fnDown(ev);
return false;
};
};
Drag.prototype.fnDown = function(ev) {
var This = this;
this.disX = ev.clientX – this.oDiv.offsetLeft;
this.disY = ev.clientY – this.oDiv.offsetTop;
document.onmousemove = function(ev) {
var ev = ev || window.event;
This.fnMove(ev);
};
document.onmouseup = function() {
This.fnUp();
}
};
Drag.prototype.fnMove = function(ev) {
this.oDiv.style.left = ev.clientX – this.disX + ‘px’;
this.oDiv.style.top = ev.clientY – this.disY + ‘px’;
};
Drag.prototype.fnUp = function() {
document.onmousemove = null;
document.onmouseup = null;
};
15. 函数节流(throttle)
//fn 要执行的函数
//delay 延迟
//atleast 在 time 时间内必须执行一次
function throttle(fn, delay, atleast) {
var timeout = null,
startTime = new Date();
return function() {
var curTime = new Date();
clearTimeout(timeout);
// 如果达到了规定的触发时间间隔,触发 handler
if(curTime – startTime >= atleast) {
fn();
startTime = curTime;
}else {
// 没达到触发间隔,重新设定定时器
timeout = setTimeout(fn, delay);
}
}
}
// 实际想绑定在 scroll 事件上的 handler
function lazyload(event) {
console.log(‘ 触发了 ’)
}
// 采用了节流函数
window.addEventListener(‘scroll’,throttle(lazyload,500,1000));
16. 函数去抖(debounce)
// debounce 函数用来包裹我们的事件
function debounce(fn, delay) {
// 持久化一个定时器 timer
let timer = null;
return function() {
// 如果事件被触发,清除 timer 并重新开始计时
clearTimeout(timer);
timer = setTimeout(function() {
fn();
}, delay);
}
}
// 实际想绑定在 scroll 事件上的 handler
function lazyload(event) {
console.log(‘ 触发了 ’)
}
// 采用了去抖函数
window.addEventListener(‘scroll’,debounce(lazyload,500));
17. 分时函数
如果一次获得了很多数据(比如有 10W 数据),然后在前端渲染的时候会卡到爆, 所以在处理这么多数据的时候,我们可以选择分批进行。
function timeChunk(data, fn, count = 1, wait) {
let obj, timer;
function start() {
let len = Math.min(count, data.length);
for (let i = 0; i < len; i++) {
val = data.shift(); // 每次取出一个数据,传给 fn 当做值来用
fn(val);
}
}
return function() {
timer = setInterval(function() {
if (data.length === 0) {// 如果数据为空了,就清空定时器
return clearInterval(timer);
}
start();
}, wait); // 分批执行的时间间隔
}
}
// 测试用例
let arr = [];
for (let i = 0; i < 100000; i++) {// 这里跑了 10 万数据
arr.push(i);
}
let render = timeChunk(arr, function(n) {// n 为 data.shift()取到的数据
let div = document.createElement(‘div’);
div.innerHTML = n;
document.body.appendChild(div);
}, 8, 20);
render();
参考文章:高阶函数,你怎么那么漂亮呢!
18. 惰性载入函数
假如你要写一个函数,里面有一些判断语句
function foo(){
if(a != b){
console.log(‘aaa’)
}else{
console.log(‘bbb’)
}
}
如果你的 a 和 b 是不变的,那么这个函数不论执行多少次,结果都是不变的,但是每次执行还要进行 if 判断,这就造成了不必要的浪费。惰性载入表示函数执行的分支只会发生一次,这里有两种解决方式。
// 常见的例子
if (window.addEventListener) {
ele.addEventListener(type, fn, false);
} else if (window.attachEvent) {
ele.attachEvent(‘on’ + type, fn);
}
在函数被调用时再处理函数
function foo(){
if(a != b){
foo = function(){
console.log(‘aaa’)
}
}else{
foo = function(){
console.log(‘bbb’)
}
}
return foo();
}
这样进入每个分支后都会对 foo 进行赋值,覆盖了之前的函数,之后每次调用 foo 就不会再执行 if 判断
在声明函数时就指定适当的函数
var foo = (function foo(){
if(a != b){
return function(){
console.log(‘aaa’)
}
}else{
return function(){
console.log(‘bbb’)
}
}
})();
本节参考文章:JS 高级技巧(简洁版)
19. 实现 once 函数
function test(){
alert(‘hello’);
}
var once = function (fn) {
var isFirst = true;
return function () {
if (isFirst) {
isFirst = !isFirst;
fn();
}
};
};
once(test);
once(test);
20.requirejs 架子
require.js 的诞生,就是为了解决这两个问题:
实现 js 文件的异步加载,避免网页失去响应;
管理模块之间的依赖性,便于代码的编写和维护。
/** 网页中引入 require.js 及 main.js **/
<script src=”js/require.js” data-main=”js/main”></script>
/** main.js 入口文件 / 主模块 **/
// 首先用 config()指定各模块路径和引用名
require.config({
baseUrl: “js/lib”,
paths: {
“jquery”: “jquery.min”, // 实际路径为 js/lib/jquery.min.js
“underscore”: “underscore.min”,
}
});
// 执行基本操作
require([“jquery”,”underscore”],function($,_){
// some code here
});
引用模块的时候,我们将模块名放在 [] 中作为 reqiure()的第一参数;如果我们定义的模块本身也依赖其他模块, 那就需要将它们放在 [] 中作为 define()的第一参数。
// 定义 math.js 模块
define(function () {
var basicNum = 0;
var add = function (x, y) {
return x + y;
};
return {
add: add,
basicNum :basicNum
};
});
// 定义一个依赖 underscore.js 的模块
define([‘underscore’],function(_){
var classify = function(list){
_.countBy(list,function(num){
return num > 30 ? ‘old’ : ‘young’;
})
};
return {
classify :classify
};
})
// 引用模块,将模块放在 [] 内
require([‘jquery’, ‘math’],function($, math){
var sum = math.add(10,20);
$(“#sum”).html(sum);
});
加载非规范的模块理论上,require.js 加载的模块,必须是按照 AMD 规范、用 define()函数定义的模块。但是实际上,虽然已经有一部分流行的函数库(比如 jQuery)符合 AMD 规范,更多的库并不符合。那么,require.js 是否能够加载非规范的模块呢?
这样的模块在用 require()加载之前,要先用 require.config()方法,定义它们的一些特征。举例来说,underscore 和 backbone 这两个库,都没有采用 AMD 规范编写。如果要加载它们的话,必须先定义它们的特征。
require.config({
shim: {
’underscore’:{
exports: ‘_’
},
’backbone’: {
deps: [‘underscore’, ‘jquery’],
exports: ‘Backbone’
}
}
});
require.config()接受一个配置对象,这个对象除了有前面说过的 paths 属性之外,还有一个 shim 属性,专门用来配置不兼容的模块。具体来说,每个模块要定义(1)exports 值(输出的变量名),表明这个模块外部调用时的名称;(2)deps 数组,表明该模块的依赖性。
比如,jQuery 的插件可以这样定义:
shim: {
’jquery.scroll’: {
deps: [‘jquery’],
exports: ‘jQuery.fn.scroll’
}
}
require.js 插件
require.js 还提供一系列插件,实现一些特定的功能。domready 插件,可以让回调函数在页面 DOM 结构加载完成后再运行。
require([‘domready!’], function (doc){
// called once the DOM is ready
});
text 和 image 插件,则是允许 require.js 加载文本和图片文件。
define([
’text!review.txt’,
’image!cat.jpg’
],
function(review,cat){
console.log(review);
document.body.appendChild(cat);
}
);
类似的插件还有 json 和 mdown,用于加载 json 文件和 markdown 文件。
本节参考文章:require.js 的用法