預(yù)加載與JavaScript的Image()對象
發(fā)表時間:2024-06-13 來源:明輝站整理相關(guān)軟件相關(guān)文章人氣:
[摘要]很多高分辨率的圖像真的能夠扮靚一個Web網(wǎng)站。但是它們也可能會降低網(wǎng)站的(響應(yīng))速度——圖像都是文件,文件就要占用帶寬,而帶寬與等待時間直接相關(guān)。現(xiàn)在是你進(jìn)行自我學(xué)習(xí),了解如何利用一種叫做圖像預(yù)加載的小技巧給網(wǎng)站提速的時候了。圖像的預(yù)加載 瀏覽器通常的工作方式是:只有當(dāng)要求加載圖像的HTTP請求...
很多高分辨率的圖像真的能夠扮靚一個Web網(wǎng)站。但是它們也可能會降低網(wǎng)站的(響應(yīng))速度——圖像都是文件,文件就要占用帶寬,而帶寬與等待時間直接相關(guān),F(xiàn)在是你進(jìn)行自我學(xué)習(xí),了解如何利用一種叫做圖像預(yù)加載的小技巧給網(wǎng)站提速的時候了。
圖像的預(yù)加載
瀏覽器通常的工作方式是:只有當(dāng)要求加載圖像的HTTP請求被發(fā)送的時候,圖像才會被加載,而不論它是被動地通過<img>標(biāo)記加載,還是主動地通過方法調(diào)用加載。所以,如果你有一段JavaScript,需要在鼠標(biāo)懸停的時候切換圖像,或者在超時之后自動地更換圖像,那么你就可能會在從服務(wù)器取回圖像的時候隨時碰到等待,時間會從數(shù)秒鐘到幾分鐘不等。當(dāng)你以較慢的速度連接到Internet上的時候,或者被取回的圖像非常巨大的時候,這種狀況尤其顯著,而這種數(shù)據(jù)延遲通常都會毀掉你所期望的效果。
有些瀏覽器會試圖轉(zhuǎn)嫁這一問題,比如把圖像保存在本地緩沖區(qū)里,這樣以后對它的調(diào)用就能夠很快進(jìn)行了,但是需要第一次調(diào)用圖像的時候仍然會產(chǎn)生延遲。預(yù)加載是一項在需要圖像之前就把它下載到緩沖區(qū)里的技術(shù)。通過這種方式,當(dāng)真的需要圖像的時候,它可以被從緩沖區(qū)里取出來,并立即顯示出來。
Image()對象
預(yù)加載圖像最簡單的方法用JavaScript將一個新的Image()對象實例化,并把你想要預(yù)加載的圖像的URL傳遞給它。假設(shè)我們有一個叫做http://cfan.net.cn/info/heavyimagefile.jpg的圖像,我們希望,當(dāng)用戶把鼠標(biāo)放在一個已經(jīng)顯示過的圖像上的時,系統(tǒng)能夠顯示出這個圖像。為了預(yù)加載這個圖像,以便實現(xiàn)更快的響應(yīng)時間,我們只用創(chuàng)建一個新的Image()對象,將其命名為heavyImage,并使用onLoad()事件處理程序把它同時加載到頁面上。
<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)記自身并不會處理onMouseOver()和onMouseOut()事件,這就是為什么上面例子里的<img>標(biāo)記被放在一個<a>標(biāo)記里,后者的確加入了對這些事件類型的支持。
用數(shù)組加載多個圖像
在實際操作中,你可能需要預(yù)加載一幅以上的圖像;例如,在包含有多個圖像翻滾(rollover)的菜單條里,或者如果你正在嘗試創(chuà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()對象。然后定義一個叫做images[]的新數(shù)組,在這個數(shù)組里,每個數(shù)組元素都保存著需要預(yù)加載的圖像來源。最后,創(chuàng)建一個for()循環(huán),讓它在數(shù)組里循環(huán),并將它們中的每一個都指派給Image()對象,這樣就能夠把它預(yù)加載到緩沖區(qū)里。
onLoad()事件處理程序
就和JavaScript里的其它很多對象一樣,Image()對象也帶有多個事件處理程序。這其中最有用的毫無疑問的就是onLoad()處理程序了,它會在完成圖像加載的時候被調(diào)用。這個處理程序可以與自定義的函數(shù)一起使用,以便在完成圖像加載之后進(jìn)行特定的任務(wù)。下面的例子通過在圖像加載的時候顯示“請等待(please wait)”提示信息來說明這個問題,然后在圖像完成加載之后就向瀏覽器發(fā)送一個新的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)建一個圖像數(shù)組,對它進(jìn)行循環(huán),預(yù)加載每個圖像,并在每個階段對已加載圖像的數(shù)量保持跟蹤。一旦加載了所有的圖像,事件處理程序就能夠按照設(shè)定把瀏覽器帶到下一個頁面(或者進(jìn)行其他的任務(wù))。
預(yù)加載與多狀態(tài)菜單
現(xiàn)在,把你剛剛學(xué)到的理論付諸真正的實踐怎么樣?下面一部分內(nèi)容就是我碰巧編寫的一段代碼——一個由多個按鈕(圖像鏈接)組成的菜單條——其中每個按鈕都可能處于三種狀態(tài)中的一種:正常(normal)、hover(懸停)和點擊(click)。由于所有的按鈕都有多個狀態(tài),所以就有必要使用圖像預(yù)加載來確保菜單能夠根據(jù)其切換到的狀態(tài)進(jìn)行快速的響應(yīng)。列表A里的代碼就說了這一點。
列表A里的HTML代碼會建立一個由四個按鈕組成的菜單條,每個按鈕都有三種狀態(tài):正常、懸停和點擊。其要求如下:
但鼠標(biāo)移動到處于正常狀態(tài)的按鈕上時,按鈕會變?yōu)閼彝顟B(tài)。當(dāng)鼠標(biāo)移開的時候,按鈕又會恢復(fù)到正常狀態(tài)。
當(dāng)鼠標(biāo)點擊按鈕的時候,按鈕就會變?yōu)辄c擊狀態(tài)。它會一直保持這個狀態(tài),直到另外一個按鈕被點擊。
如果有一個按鈕被點擊,那么其他的按鈕就都不能處于點擊狀態(tài)。其他的按鈕只能夠處于懸停或者正常狀態(tài)。
一次只能有一個按鈕可以被點擊。
一次只能有一個按鈕處于懸停狀態(tài)。
第一項任務(wù)是建立保存有菜單每個狀態(tài)的圖像的數(shù)組。與這些數(shù)組元素相對應(yīng)的<img>元素也都在HTML文檔的主體里被創(chuàng)建,并按順序命名。要注意的是,對數(shù)組值的索引是從0開始的,而相應(yīng)的<img>元素是從1開始命名的——這就需要在腳本后面的一段里進(jìn)行某種計算上的調(diào)整。
PreloadImages()函數(shù)會負(fù)責(zé)把所有的圖像都加載到緩沖區(qū)里,這樣的話對鼠標(biāo)移動的響應(yīng)時間會被減到最小。一個for()循環(huán)被用在第一步里創(chuàng)建的圖像里進(jìn)行迭代,并預(yù)加載每一個圖像。
ResetAll()函數(shù)是把所有圖像恢復(fù)都到它們正常狀態(tài)的方便方法。這是有必要的,因為當(dāng)菜單的項目被點擊的時候,菜單里其他所有的項目都必須在被點擊項目能夠切換到點擊狀態(tài)之前恢復(fù)到正常狀態(tài)。
SetNormal()、setHover()和setClick()函數(shù)負(fù)責(zé)把特定圖像(圖像的編號被作為函數(shù)的自變量進(jìn)行傳遞)的來源分別改為正常、懸停或者點擊狀態(tài)。由于被點擊的圖像必須一直保持點擊狀態(tài),直到另外一個圖像被點擊(見第二項要求),所以它們暫時不會對鼠標(biāo)移動作出反應(yīng);這樣的話,如果按鈕還不是處在點擊狀態(tài),那么setNormal()和setHover()函數(shù)所包括的代碼就只能用來改變按鈕的狀態(tài)。
上面所提到的預(yù)加載只是提高你JavaScript效果響應(yīng)時間的多種方法之一。就在你的網(wǎng)站上使用上面列出的技巧,并根據(jù)你的要求在需要的地方更改它們吧。祝你好運!