明輝手游網(wǎng)中心:是一個(gè)免費(fèi)提供流行視頻軟件教程、在線(xiàn)學(xué)習(xí)分享的學(xué)習(xí)平臺(tái)!

預(yù)加載與JavaScript的Image()對(duì)象

[摘要]很多高分辨率的圖像真的能夠扮靚一個(gè)Web網(wǎng)站。但是它們也可能會(huì)降低網(wǎng)站的(響應(yīng))速度——圖像都是文件,文件就要占用帶寬,而帶寬與等待時(shí)間直接相關(guān)。現(xiàn)在是你進(jìn)行自我學(xué)習(xí),了解如何利用一種叫做圖像預(yù)加載的小技巧給網(wǎng)站提速的時(shí)候了。圖像的預(yù)加載 瀏覽器通常的工作方式是:只有當(dāng)要求加載圖像的HTTP請(qǐng)求...
很多高分辨率的圖像真的能夠扮靚一個(gè)Web網(wǎng)站。但是它們也可能會(huì)降低網(wǎng)站的(響應(yīng))速度——圖像都是文件,文件就要占用帶寬,而帶寬與等待時(shí)間直接相關(guān)。現(xiàn)在是你進(jìn)行自我學(xué)習(xí),了解如何利用一種叫做圖像預(yù)加載的小技巧給網(wǎng)站提速的時(shí)候了。

圖像的預(yù)加載


瀏覽器通常的工作方式是:只有當(dāng)要求加載圖像的HTTP請(qǐng)求被發(fā)送的時(shí)候,圖像才會(huì)被加載,而不論它是被動(dòng)地通過(guò)<img>標(biāo)記加載,還是主動(dòng)地通過(guò)方法調(diào)用加載。所以,如果你有一段JavaScript,需要在鼠標(biāo)懸停的時(shí)候切換圖像,或者在超時(shí)之后自動(dòng)地更換圖像,那么你就可能會(huì)在從服務(wù)器取回圖像的時(shí)候隨時(shí)碰到等待,時(shí)間會(huì)從數(shù)秒鐘到幾分鐘不等。當(dāng)你以較慢的速度連接到Internet上的時(shí)候,或者被取回的圖像非常巨大的時(shí)候,這種狀況尤其顯著,而這種數(shù)據(jù)延遲通常都會(huì)毀掉你所期望的效果。

有些瀏覽器會(huì)試圖轉(zhuǎn)嫁這一問(wèn)題,比如把圖像保存在本地緩沖區(qū)里,這樣以后對(duì)它的調(diào)用就能夠很快進(jìn)行了,但是需要第一次調(diào)用圖像的時(shí)候仍然會(huì)產(chǎn)生延遲。預(yù)加載是一項(xiàng)在需要圖像之前就把它下載到緩沖區(qū)里的技術(shù)。通過(guò)這種方式,當(dāng)真的需要圖像的時(shí)候,它可以被從緩沖區(qū)里取出來(lái),并立即顯示出來(lái)。

Image()對(duì)象
預(yù)加載圖像最簡(jiǎn)單的方法用JavaScript將一個(gè)新的Image()對(duì)象實(shí)例化,并把你想要預(yù)加載的圖像的URL傳遞給它。假設(shè)我們有一個(gè)叫做http://cfan.net.cn/info/heavyimagefile.jpg的圖像,我們希望,當(dāng)用戶(hù)把鼠標(biāo)放在一個(gè)已經(jīng)顯示過(guò)的圖像上的時(shí),系統(tǒng)能夠顯示出這個(gè)圖像。為了預(yù)加載這個(gè)圖像,以便實(shí)現(xiàn)更快的響應(yīng)時(shí)間,我們只用創(chuàng)建一個(gè)新的Image()對(duì)象,將其命名為heavyImage,并使用onLoad()事件處理程序把它同時(shí)加載到頁(yè)面上。

<html><head><script language = "JavaScript">function preloader() {heavyImage = new Image(); heavyImage.src = "http://cfan.net.cn/info/heavyimagefile.jpg";}</script></head><body onLoad="javascript:preloader()"><a href="#" onMouseOver="javascript:document.img01.src='http://cfan.net.cn/info/heavyimagefile.jpg'"><img name="img01" src=http://cfan.net.cn/info/"justanotherfile.jpg"></a></body></html>
要注意的是,圖像標(biāo)記自身并不會(huì)處理onMouseOver()和onMouseOut()事件,這就是為什么上面例子里的<img>標(biāo)記被放在一個(gè)<a>標(biāo)記里,后者的確加入了對(duì)這些事件類(lèi)型的支持。
用數(shù)組加載多個(gè)圖像


在實(shí)際操作中,你可能需要預(yù)加載一幅以上的圖像;例如,在包含有多個(gè)圖像翻滾(rollover)的菜單條里,或者如果你正在嘗試創(chuàng)建平滑的動(dòng)態(tài)效果。這并不困難;你所需要做的就是使用JavaScript的數(shù)組,就像下面例子里的一樣:

<script language="JavaScript">function preloader() { // counter var i = 0; // create object imageObj = new Image(); // set image list images = new Array(); images[0]="image1.jpg" images[1]="image2.jpg" images[2]="image3.jpg" images[3]="image4.jpg" // start preloading for(i=0; i<=3; i++) { imageObj.src=images[i]; }
} </script>
在上面的例子里,你先定義變量i和叫做imageObj的Image()對(duì)象。然后定義一個(gè)叫做images[]的新數(shù)組,在這個(gè)數(shù)組里,每個(gè)數(shù)組元素都保存著需要預(yù)加載的圖像來(lái)源。最后,創(chuàng)建一個(gè)for()循環(huán),讓它在數(shù)組里循環(huán),并將它們中的每一個(gè)都指派給Image()對(duì)象,這樣就能夠把它預(yù)加載到緩沖區(qū)里。
onLoad()事件處理程序
就和JavaScript里的其它很多對(duì)象一樣,Image()對(duì)象也帶有多個(gè)事件處理程序。這其中最有用的毫無(wú)疑問(wèn)的就是onLoad()處理程序了,它會(huì)在完成圖像加載的時(shí)候被調(diào)用。這個(gè)處理程序可以與自定義的函數(shù)一起使用,以便在完成圖像加載之后進(jìn)行特定的任務(wù)。下面的例子通過(guò)在圖像加載的時(shí)候顯示“請(qǐng)等待(please wait)”提示信息來(lái)說(shuō)明這個(gè)問(wèn)題,然后在圖像完成加載之后就向?yàn)g覽器發(fā)送一個(gè)新的URL。

<html><head><script language="JavaScript">// create an image objectobjImage = new Image(); // set what happens once the image has loaded objImage.onLoad=imagesLoaded(); // preload the image fileobjImage.src='http://cfan.net.cn/info/images/image1n.gif';// function invoked on image loadfunction imagesLoaded(){ document.location.href='index2.html';}</script></head><body>Please wait, loading images...</body></html>


當(dāng)然,你還可以創(chuàng)建一個(gè)圖像數(shù)組,對(duì)它進(jìn)行循環(huán),預(yù)加載每個(gè)圖像,并在每個(gè)階段對(duì)已加載圖像的數(shù)量保持跟蹤。一旦加載了所有的圖像,事件處理程序就能夠按照設(shè)定把瀏覽器帶到下一個(gè)頁(yè)面(或者進(jìn)行其他的任務(wù))。

預(yù)加載與多狀態(tài)菜單
現(xiàn)在,把你剛剛學(xué)到的理論付諸真正的實(shí)踐怎么樣?下面一部分內(nèi)容就是我碰巧編寫(xiě)的一段代碼——一個(gè)由多個(gè)按鈕(圖像鏈接)組成的菜單條——其中每個(gè)按鈕都可能處于三種狀態(tài)中的一種:正常(normal)、hover(懸停)和點(diǎn)擊(click)。由于所有的按鈕都有多個(gè)狀態(tài),所以就有必要使用圖像預(yù)加載來(lái)確保菜單能夠根據(jù)其切換到的狀態(tài)進(jìn)行快速的響應(yīng)。列表A里的代碼就說(shuō)了這一點(diǎn)。

列表A里的HTML代碼會(huì)建立一個(gè)由四個(gè)按鈕組成的菜單條,每個(gè)按鈕都有三種狀態(tài):正常、懸停和點(diǎn)擊。其要求如下:

但鼠標(biāo)移動(dòng)到處于正常狀態(tài)的按鈕上時(shí),按鈕會(huì)變?yōu)閼彝顟B(tài)。當(dāng)鼠標(biāo)移開(kāi)的時(shí)候,按鈕又會(huì)恢復(fù)到正常狀態(tài)。
當(dāng)鼠標(biāo)點(diǎn)擊按鈕的時(shí)候,按鈕就會(huì)變?yōu)辄c(diǎn)擊狀態(tài)。它會(huì)一直保持這個(gè)狀態(tài),直到另外一個(gè)按鈕被點(diǎn)擊。
如果有一個(gè)按鈕被點(diǎn)擊,那么其他的按鈕就都不能處于點(diǎn)擊狀態(tài)。其他的按鈕只能夠處于懸;蛘哒顟B(tài)。
一次只能有一個(gè)按鈕可以被點(diǎn)擊。
一次只能有一個(gè)按鈕處于懸停狀態(tài)。
第一項(xiàng)任務(wù)是建立保存有菜單每個(gè)狀態(tài)的圖像的數(shù)組。與這些數(shù)組元素相對(duì)應(yīng)的<img>元素也都在HTML文檔的主體里被創(chuàng)建,并按順序命名。要注意的是,對(duì)數(shù)組值的索引是從0開(kāi)始的,而相應(yīng)的<img>元素是從1開(kāi)始命名的——這就需要在腳本后面的一段里進(jìn)行某種計(jì)算上的調(diào)整。

PreloadImages()函數(shù)會(huì)負(fù)責(zé)把所有的圖像都加載到緩沖區(qū)里,這樣的話(huà)對(duì)鼠標(biāo)移動(dòng)的響應(yīng)時(shí)間會(huì)被減到最小。一個(gè)for()循環(huán)被用在第一步里創(chuàng)建的圖像里進(jìn)行迭代,并預(yù)加載每一個(gè)圖像。

ResetAll()函數(shù)是把所有圖像恢復(fù)都到它們正常狀態(tài)的方便方法。這是有必要的,因?yàn)楫?dāng)菜單的項(xiàng)目被點(diǎn)擊的時(shí)候,菜單里其他所有的項(xiàng)目都必須在被點(diǎn)擊項(xiàng)目能夠切換到點(diǎn)擊狀態(tài)之前恢復(fù)到正常狀態(tài)。

SetNormal()、setHover()和setClick()函數(shù)負(fù)責(zé)把特定圖像(圖像的編號(hào)被作為函數(shù)的自變量進(jìn)行傳遞)的來(lái)源分別改為正常、懸;蛘唿c(diǎn)擊狀態(tài)。由于被點(diǎn)擊的圖像必須一直保持點(diǎn)擊狀態(tài),直到另外一個(gè)圖像被點(diǎn)擊(見(jiàn)第二項(xiàng)要求),所以它們暫時(shí)不會(huì)對(duì)鼠標(biāo)移動(dòng)作出反應(yīng);這樣的話(huà),如果按鈕還不是處在點(diǎn)擊狀態(tài),那么setNormal()和setHover()函數(shù)所包括的代碼就只能用來(lái)改變按鈕的狀態(tài)。

上面所提到的預(yù)加載只是提高你JavaScript效果響應(yīng)時(shí)間的多種方法之一。就在你的網(wǎng)站上使用上面列出的技巧,并根據(jù)你的要求在需要的地方更改它們吧。祝你好運(yùn)!