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