JSI暫時(shí)不大算編寫(xiě)豐富的公共API,但是我們可以集成其他成熟的類(lèi)庫(kù),同時(shí)隔離他們的依賴(lài),隔離各個(gè)腳本的執(zhí)行上下文,消除命名沖突的危險(xiǎn)。
這里我們?cè)敿?xì)介紹一個(gè)復(fù)雜一點(diǎn)的實(shí)例:類(lèi)似Windows XP文件瀏覽器左側(cè)的滑動(dòng)折疊面板(任務(wù)菜單)效果。
我們先集成Scriptaculous Effect類(lèi)庫(kù),并且在這個(gè)基礎(chǔ)上按我個(gè)人的習(xí)慣對(duì)一個(gè)面板折疊效果做一個(gè)簡(jiǎn)單的封裝,展示框架的類(lèi)庫(kù)封裝功能。
1。集成Scriptaculous類(lèi)庫(kù):
這里我們不做過(guò)多介紹,詳細(xì)情況請(qǐng)參考集成實(shí)戰(zhàn);我們發(fā)布的版本中已經(jīng)把Scriptaculous放置于us.aculo.script包中,您可以把這些作為系統(tǒng)內(nèi)置的類(lèi)庫(kù)使用。
2。編寫(xiě)我們的折疊面板函數(shù)(example/effect.js):
/**
* 滑動(dòng)面板實(shí)現(xiàn).
* 當(dāng)指定元素可見(jiàn)時(shí),將其第一個(gè)子元素向上滑動(dòng)至完全被遮掩(折疊)。
* 當(dāng)指定元素不可見(jiàn)時(shí),將其第一個(gè)子元素向下滑動(dòng)至完全顯示(展開(kāi))。
*/
function slidePanel(panel){
panel = $(panel);
if(panel.style.display=='none'){
//調(diào)用Scriptaculous Effect的具體滑動(dòng)展開(kāi)實(shí)現(xiàn)
new Effect.SlideDown(panel);
}else{
//調(diào)用Scriptaculous Effect的具體滑動(dòng)閉合實(shí)現(xiàn)
new Effect.SlideUp(panel);
}
}
* 滑動(dòng)面板實(shí)現(xiàn).
* 當(dāng)指定元素可見(jiàn)時(shí),將其第一個(gè)子元素向上滑動(dòng)至完全被遮掩(折疊)。
* 當(dāng)指定元素不可見(jiàn)時(shí),將其第一個(gè)子元素向下滑動(dòng)至完全顯示(展開(kāi))。
*/
function slidePanel(panel){
panel = $(panel);
if(panel.style.display=='none'){
//調(diào)用Scriptaculous Effect的具體滑動(dòng)展開(kāi)實(shí)現(xiàn)
new Effect.SlideDown(panel);
}else{
//調(diào)用Scriptaculous Effect的具體滑動(dòng)閉合實(shí)現(xiàn)
new Effect.SlideUp(panel);
}
}
3。編寫(xiě)包定義腳本(example/__$package.js):
//添加slidePanel(滑動(dòng)面板控制)函數(shù)
this.addScript("effect.js","slidePanel",null);
//給effect.js腳本添加對(duì)us.aculo.script包中effects.js腳本的裝載后依賴(lài)this.addScriptDependence("effect.js",
"us/aculo/script/effects.js",false);
this.addScript("effect.js","slidePanel",null);
//給effect.js腳本添加對(duì)us.aculo.script包中effects.js腳本的裝載后依賴(lài)this.addScriptDependence("effect.js",
"us/aculo/script/effects.js",false);
4。在網(wǎng)頁(yè)上運(yùn)用上面的類(lèi)庫(kù):
<html>
<head>
<title>重用aculo Effect腳本實(shí)例</title>
<link rel="stylesheet" type="text/css" href="/styles/default.css" />
<script src="/scripts/boot.js"></script>
<script>
$import("example.slidePanel");
</script>
</head>
<body>
<div class="menu_header"
onclick="slidePanel('menu_block1')">
面板 1
</div>
<div class="menu_block" id="menu_block1">
<ul>
<li>text1</li>
<li>text2</li>
<li>text3</li>
</ul>
</div>
</body>
</html>
<head>
<title>重用aculo Effect腳本實(shí)例</title>
<link rel="stylesheet" type="text/css" href="/styles/default.css" />
<script src="/scripts/boot.js"></script>
<script>

$import("example.slidePanel");
</script>
</head>
<body>
<div class="menu_header"
onclick="slidePanel('menu_block1')">
面板 1
</div>
<div class="menu_block" id="menu_block1">
<ul>
<li>text1</li>
<li>text2</li>
<li>text3</li>
</ul>
</div>
</body>
</html>
onclick="slidePanel('menu_block1')"這個(gè)事件函數(shù)將在我們點(diǎn)擊面板標(biāo)題時(shí)觸發(fā),能后會(huì)調(diào)用Scriptaculous Effect的具體實(shí)現(xiàn)去實(shí)現(xiàn)我們需要的滑動(dòng)折疊功能。
壁立千仞 無(wú)欲則剛――控制依賴(lài)
java可以隨意的使用第三方類(lèi)庫(kù),可是JavaScript卻沒(méi)那么幸運(yùn),隨著類(lèi)庫(kù)的豐富,煩雜的依賴(lài)關(guān)系和可能的命名沖突將使得類(lèi)庫(kù)的發(fā)展越來(lái)越困難。程序的易用性也將大打折扣。
命名沖突的危險(xiǎn)無(wú)形的增加你大腦的負(fù)擔(dān);隨著使用的類(lèi)庫(kù)的增加,暴露的依賴(lài)也將隨之增加,這是復(fù)雜度陡增的極大禍根,將使得系統(tǒng)越來(lái)越復(fù)雜,越來(lái)越難以控制。潛在的問(wèn)題越來(lái)越多,防不勝防。
JSI的出現(xiàn),可以解決上述問(wèn)題,我們建議類(lèi)庫(kù)的開(kāi)發(fā)者將自己類(lèi)庫(kù)的依賴(lài)終結(jié)在自己手中,避免依賴(lài)擴(kuò)散,以提高類(lèi)庫(kù)的易用性。
同樣使用上面的例子,假如我們想拋開(kāi)JSI,實(shí)現(xiàn)同樣的功能,那我們的頁(yè)面代碼將是(類(lèi)庫(kù)代碼不用改動(dòng)):
<html>
<head>
<title>重用aculo Effect腳本實(shí)例</title>
<link rel="stylesheet" type="text/css" href="/styles/default.css" />
<!--
<script src="/scripts/boot.js"></s cript>
<script>
$import("example.slidePanel");
</sc ript>
-->
<script src="/scripts/net/conio/prototype/v1_5/prototype.js">
</script>
<script src="/scripts/us/aculo/script/v1_7/effects.js">
</script>
<script src="/scripts/us/aculo/script/v1_7/builder.js">
</script>
<script src="/scripts/example/effect.js">
</script>
</head>
<body>
<div class="menu_header"
onclick="slidePanel('menu_block1')">
面板 1
</div>
<div class="menu_block" id="menu_block1">
<ul>
<li>text1</li>
<li>text2</li>
<li>text3</li>
</ul>
</div>
</body>
</html>
<head>
<title>重用aculo Effect腳本實(shí)例</title>
<link rel="stylesheet" type="text/css" href="/styles/default.css" />
<!--
<script src="/scripts/boot.js"></s cript>
<script>
$import("example.slidePanel");
</sc ript>
-->
<script src="/scripts/net/conio/prototype/v1_5/prototype.js">
</script>
<script src="/scripts/us/aculo/script/v1_7/effects.js">
</script>
<script src="/scripts/us/aculo/script/v1_7/builder.js">
</script>
<script src="/scripts/example/effect.js">
</script>
</head>
<body>
<div class="menu_header"
onclick="slidePanel('menu_block1')">
面板 1
</div>
<div class="menu_block" id="menu_block1">
<ul>
<li>text1</li>
<li>text2</li>
<li>text3</li>
</ul>
</div>
</body>
</html>
這個(gè)例子的html代碼明顯比上面的復(fù)雜了,一堆堆的script標(biāo)簽,而且還是有序的;還出現(xiàn)在頁(yè)面上,重構(gòu)起來(lái)也極其麻煩。
可以看出,JSI的加入可以讓類(lèi)庫(kù)更加易用,html代碼更為簡(jiǎn)潔,最終用戶(hù)已經(jīng)不必關(guān)心所用類(lèi)庫(kù)的依賴(lài)了。
JSI中每一個(gè)腳本有一個(gè)單獨(dú)的執(zhí)行上下文。各個(gè)腳本頂部變量你可以隨便使用,不必?fù)?dān)心不同腳本中的命名沖突,不會(huì)污染全局變量空間,這種方式可以用于解 決某些類(lèi)庫(kù)間變量沖突的問(wèn)題(如jQuery和Prototype的$函數(shù))。我們甚至可以做到同一個(gè)頁(yè)面上間接加載同一種類(lèi)庫(kù)的兩個(gè)不同版本,不相互影 響。
使用JSI后,很多細(xì)節(jié)我們可以在包中封裝掉,不需要告訴類(lèi)庫(kù)使用者太多。大大增加類(lèi)庫(kù)的易用性。同時(shí),類(lèi)庫(kù)封裝的支持可以讓我們?cè)诘谌綆?kù)的基礎(chǔ)上輕松的按自己的喜好編寫(xiě)自己的類(lèi)庫(kù),同時(shí)避免依賴(lài)擴(kuò)散造成的復(fù)雜度增加。
使用JSIntegration唯一多出的負(fù)擔(dān)就是編寫(xiě)包定義文件,不過(guò)想想這種定義文件可是一勞永逸的(以后就不需要每次導(dǎo)入腳本的時(shí)候都小心翼翼的判 斷那個(gè)腳本先導(dǎo)入那個(gè)后導(dǎo)入,有那些間接使用到的類(lèi)庫(kù)需要導(dǎo)入,等等),而且有了包結(jié)構(gòu)后對(duì)于代碼組織、重用,以及文檔的編寫(xiě)閱讀,都將非常有利。