就是為了解決命名沖突和文件依賴的問題的曲掰。
之前用jquery寫的豆瓣電影疾捍,是對(duì)象封裝寫的,demo栏妖。
可以先看下源碼乱豆,然后對(duì)比下的。
然后用RequireJS寫一下吊趾,先說宛裕,模塊在這里就是封裝的那幾個(gè)對(duì)象了,思路是什么呢论泛?
把這幾個(gè)對(duì)象當(dāng)成模塊揩尸,那就是一個(gè)個(gè)的獨(dú)立的js文件,這些模塊屁奏,必須要定義岩榆,一定義,就要用RequireJS里的函數(shù):
define([所有依賴的模塊文件路徑字符串格式的數(shù)組],function(x,y,z,,,){
,,,
,,,
return ,,,
}) //x,y,z,,,是定義的模塊加載執(zhí)行后返回的內(nèi)容的變量
先看下文件目錄us,top250,search,jquery,heap,app都是模塊,其中app的作用是啟動(dòng)管理他們的勇边,app就是依賴他們的犹撒。而main是RequireJS的一個(gè)橋梁,連接作用到app這個(gè)啟動(dòng)器的粒褒。這樣识颊,引入RequireJS文件,被執(zhí)行就找到main文件怀浆,main里require那個(gè)啟動(dòng)管理的模塊app ,然后app運(yùn)行又依賴其他的幾個(gè)模塊谊囚,其他幾個(gè)模塊又被加載執(zhí)行了,其他的模塊又有依賴的执赡,就又加載執(zhí)行镰踏,,沙合,這樣代碼就跑起來了奠伪。
這就是加載RequireJS,里面的data-main是相對(duì)于這個(gè)html去定位要作用的文件首懈,就是那個(gè)要require模塊的文件.
require.config是配置的绊率,設(shè)置了之后,對(duì)于文件路徑究履,默認(rèn)是js文件夾的根目錄下滤否,書寫方便。
下面那個(gè)就是RequireJS的第二個(gè)函數(shù)了最仑,一個(gè)是定義模塊藐俺,一個(gè)是引入模塊執(zhí)行。
這里就是引入了模塊們中的那個(gè)啟動(dòng)所有模塊的控制臺(tái)app了泥彤。這里回調(diào)函數(shù)的參數(shù)可以隨便寫欲芹,都是指向被引用的模塊執(zhí)行后返回的對(duì)象。下面可以印證一下的:
剩下的就是簡(jiǎn)單了吟吝,定義各個(gè)模塊菱父,然后設(shè)置模塊被引用時(shí)要返回的對(duì)象。
看定義的寫法剑逃,先是它依賴的模塊浙宜,這些依賴的意思換從前就是這個(gè)對(duì)象里沒有的變量或者方法的說法,看app.init()就直接跑通了所有模塊了吧蛹磺。
還有return app梆奈,回應(yīng)上面說的require吧。
再称开,分別看看其他模塊亩钟,除了jquery那個(gè)特殊乓梨,不需要定義的,直接把源碼放進(jìn)去就行了清酥,在回調(diào)函數(shù)里扶镀,返回值我用$指代了。
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"> 劇情 / 動(dòng)作/ 犯罪 </span>
</div>
<div class="mes">
導(dǎo)演:<span class="director">就死按建設(shè)</span>
</div>
<div class="mes">
主演:<span class="actor">張國榮 焰轻、 張豐毅 臭觉、鞏俐 、葛優(yōu) </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
})
自己做了一遍,覺得跟想象的不一樣揩懒,不抽象了什乙,有個(gè)錯(cuò)誤,就是jquery的版本如果是高版本的已球,就會(huì)報(bào)錯(cuò)臣镣,我也不知道為什么,挺別扭的智亮。
實(shí)際感受
因?yàn)槟K很少忆某,也沒有體現(xiàn)出太多優(yōu)點(diǎn)來,不過很明顯阔蛉,很條理弃舒,反正代碼維護(hù)起來真的很方便的。而且看看加載的方式吧状原,自己覺得很高大上的棒坏。里面有個(gè)滾動(dòng)事件的bug,太晚了遭笋,我下次更改掉,這里關(guān)鍵是RequireJS徒探。