就是为了解决命名冲突和文件依赖的问题的。
之前用jquery写的豆瓣电影,是对象封装写的,demo。
可以先看下源码,然后对比下的。
然后用RequireJS写一下,先说,模块在这里就是封装的那几个对象了,思路是什么呢?
把这几个对象当成模块,那就是一个个的独立的js文件,这些模块,必须要定义,一定义,就要用RequireJS里的函数:
define([所有依赖的模块文件路径字符串格式的数组],function(x,y,z,,,){
,,,
,,,
return ,,,
}) //x,y,z,,,是定义的模块加载执行后返回的内容的变量
先看下文件目录us,top250,search,jquery,heap,app都是模块,其中app的作用是启动管理他们的,app就是依赖他们的。而main是RequireJS的一个桥梁,连接作用到app这个启动器的。这样,引入RequireJS文件,被执行就找到main文件,main里require那个启动管理的模块app ,然后app运行又依赖其他的几个模块,其他几个模块又被加载执行了,其他的模块又有依赖的,就又加载执行,,,这样代码就跑起来了。
这就是加载RequireJS,里面的data-main是相对于这个html去定位要作用的文件,就是那个要require模块的文件.
require.config是配置的,设置了之后,对于文件路径,默认是js文件夹的根目录下,书写方便。
下面那个就是RequireJS的第二个函数了,一个是定义模块,一个是引入模块执行。
这里就是引入了模块们中的那个启动所有模块的控制台app了。这里回调函数的参数可以随便写,都是指向被引用的模块执行后返回的对象。下面可以印证一下的:
剩下的就是简单了,定义各个模块,然后设置模块被引用时要返回的对象。
看定义的写法,先是它依赖的模块,这些依赖的意思换从前就是这个对象里没有的变量或者方法的说法,看app.init()就直接跑通了所有模块了吧。
还有return app,回应上面说的require吧。
再,分别看看其他模块,除了jquery那个特殊,不需要定义的,直接把源码放进去就行了,在回调函数里,返回值我用$指代了。
define(['jquery', 'heap'], function($, heap) {
var top250 = {
init: function() {
this.$box = $('main')
this.bind()
this.start()
this.index = 0
this.$container = $('section').eq(0)
this.isloading = false
},
bind: function() {
var self = this
this.$box.scroll(function() {
if (!self.isloading && self.isbottom()) {
self.start()
}
})
},
start: function() {
var self = this
if (self.isloading) return;
self.isloading = true
heap.loading()
$.ajax({
url: 'http://api.douban.com/v2/movie/top250',
method: 'GET',
data: {
start: self.index,
count: 20
},
dataType: 'jsonp'
}).done(function(ret) {
self.judge(ret.subjects)
console.log(ret.subjects)
if (ret.subjects.length === 0) return;
self.index += 20
self.setdata(ret.subjects)
}).fail(function() {
console.log('error...')
}).always(function() {
self.isloading = false
heap.unloading()
})
},
setdata: function(data) {
var self = this
data.forEach(function(movie) {
self.$container.append(heap.build(movie))
})
},
isbottom: function() {
console.log(this.$box.height() + this.$box.scrollTop() + 10 >= this.$container.height(), 'daodile')
return this.$box.height() + this.$box.scrollTop() + 10 > this.$container.height()
},
judge: function(data) {
if (data.length === 0) {
$('.remind').css('display', 'block')
setTimeout(function() {
$('.remind').css('display', 'none')
}, 1000)
}
}
}
return top250
})
define(['jquery', 'heap'], function($, heap) {
var search = {
init: function() {
this.$box = $('main')
this.bind()
this.index = 0
this.$container = $('section').eq(2)
this.isloading = false
this.$input = $('section input')
},
bind: function() {
var self = this
$('section button').on('click', function() {
self.index = 0
self.$container.find('div').eq(0).siblings().remove()
self.start()
})
this.$box.scroll(function() {
if (self.isbottom()) {
self.start()
}
})
},
start: function() {
var self = this
if (self.isloading) return;
self.isloading = true
heap.loading()
$.ajax({
url: 'http://api.douban.com/v2/movie/search',
method: 'GET',
data: {
start: self.index,
count: 20,
tag: self.$input.val()
},
dataType: 'jsonp'
}).done(function(ret) {
//judge(ret.subjects)
if (ret.subjects.length === 0) return;
self.index += 20
self.setdata(ret.subjects)
}).fail(function() {
console.log('error...')
}).always(function() {
self.isloading = false
heap.unloading()
})
},
setdata: function(data) {
var self = this
data.forEach(function(movie) {
self.$container.append(heap.build(movie))
})
},
isbottom: function() {
return this.$box.height() + this.$box.scrollTop() + 10 >= this.$container.height()
}
}
return search
})
define(['jquery'], function(j) {
var heap = {
loading: function loading() {
$('.icon-loading').fadeIn()
},
unloading: function unloading() {
$('.icon-loading').fadeOut()
},
build: function build(movie) {
var tpl = `<div class="item">
<a href="" class="clearfix">
<img src="http://img7.doubanio.com/view/movie_poster_cover/spst/public/p480747492.jpg" alt="">
<h2>霸王别姬</h2>
<div class="mes">
<span class="score">9.0分</span>
<span> / </span>
<span class="collect">1113234收藏</span>
</div>
<div class="mes">
<span class="year">1994</span>
<sapn> / </span>
<span class="type"> 剧情 / 动作/ 犯罪 </span>
</div>
<div class="mes">
导演:<span class="director">就死按建设</span>
</div>
<div class="mes">
主演:<span class="actor">张国荣 、 张丰毅 、巩俐 、葛优 </span>
</div>
</a>
</div>`
var $node = $(tpl)
$node.find('a >img').attr('src', movie.images.medium)
$node.find('a').attr('href', movie.alt)
$node.find('a>h2').text(movie.title)
$node.find('a .score').text(movie.rating.average + '分')
$node.find('a .collect').text(movie.collect_count + '收藏')
$node.find('a .year').text(movie.year)
$node.find('a .type').text(movie.genres.join(' / '))
$node.find('a .director').text(function() {
var arr = []
movie.directors.forEach(function(obj) {
arr.push(obj.name)
return arr
})
return arr.join('、 ')
})
$node.find('a .actor').text(function() {
var arr = []
movie.casts.forEach(function(obj) {
arr.push(obj.name)
return arr
})
return arr.join('、 ')
})
return $node
}
}
return heap
})
自己做了一遍,觉得跟想象的不一样,不抽象了,有个错误,就是jquery的版本如果是高版本的,就会报错,我也不知道为什么,挺别扭的。
实际感受
因为模块很少,也没有体现出太多优点来,不过很明显,很条理,反正代码维护起来真的很方便的。而且看看加载的方式吧,自己觉得很高大上的。里面有个滚动事件的bug,太晚了,我下次更改掉,这里关键是RequireJS。