再談JavaScript圖片預(yù)加載技術(shù)
作者:唐 斌
由于JavaScript無法獲取img文件頭數(shù)據(jù),必須等待其加載完畢后才能獲取真實(shí)的大小,所以lightbox類效果為了讓圖片居中顯示,導(dǎo)致其速度體驗(yàn)要比直接輸出的差很多。而本文所提到的預(yù)加載技術(shù)主要是讓JavaScript快速獲取圖片頭部數(shù)據(jù)的尺寸。
51CTO推薦專題:JavaScript學(xué)習(xí)筆記 有問有答
一段典型的使用預(yù)加載獲取圖片大小的例子:
- var imgLoad = function (url, callback) {
- var img = new Image();
- img.src = url;
- if (img.complete) {
- callback(img.width, img.height);
- } else {
- img.onload = function () {
- callback(img.width, img.height);
- img.onload = null;
- };
- };
- };
可以看到使用onload的方式必須等待圖片加載完畢,其速度不敢恭維。
web應(yīng)用程序區(qū)別于桌面應(yīng)用程序,響應(yīng)速度才是最好的用戶體驗(yàn)。如果想要速度與優(yōu)雅兼得,那就必須提前獲得圖片尺寸,如何在圖片沒有加載完畢就能獲取圖片尺寸?
十多年的上網(wǎng)經(jīng)驗(yàn)告訴我:瀏覽器在加載圖片的時(shí)候你會(huì)看到圖片會(huì)先占用一塊地然后才慢慢加載完畢,并且這里大部分的圖片都是沒有預(yù)設(shè)width與height屬性的,因?yàn)闉g覽器能夠獲取圖片的頭部數(shù)據(jù)?;诖?,只需要使用javascript定時(shí)偵測圖片的尺寸狀態(tài)便可得知圖片尺寸就緒的狀態(tài)。
實(shí)現(xiàn)代碼:
- var imgReady = function (url, callback, error) {
- var width, height, intervalId, check, div,
- img = new Image(),
- body = document.body;
- img.src = url;
- // 從緩存中讀取
- if (img.complete) {
- return callback(img.width, img.height);
- };
- // 通過占位提前獲取圖片頭部數(shù)據(jù)
- if (body) {
- div = document.createElement('div');
- div.style.cssText = 'visibility:hidden;position:absolute;left:0;top:0;width:1px;height:1px;overflow:hidden';
- div.appendChild(img)
- body.appendChild(div);
- width = img.offsetWidth;
- height = img.offsetHeight;
- check = function () {
- if (img.offsetWidth !== width || img.offsetHeight !== height) {
- clearInterval(intervalId);
- callback(img.offsetWidth, img.clientHeight);
- img.onload = null;
- div.innerHTML = '';
- div.parentNode.removeChild(div);
- };
- };
- intervalId = setInterval(check, 150);
- };
- // 加載完畢后方式獲取
- img.onload = function () {
- callback(img.width, img.height);
- img.onload = img.onerror = null;
- clearInterval(intervalId);
- body && img.parentNode.removeChild(img);
- };
- // 圖片加載錯(cuò)誤
- img.onerror = function () {
- error && error();
- clearInterval(intervalId);
- body && img.parentNode.removeChild(img);
- };
- };
是不是很簡單?這樣的方式獲取攝影級(jí)別照片尺寸的速度往往是onload方式的幾十多倍,而對(duì)于web普通(800×600內(nèi))瀏覽級(jí)別的圖片能達(dá)到秒殺效果。
好了,請(qǐng)觀賞令人愉悅的 DEMO ,通過測試的瀏覽器:Chrome、Firefox、Safari、Opera、IE6、IE7、IE8。
原文鏈接:http://www.planeart.cn/?p=1121
【編輯推薦】
責(zé)任編輯:陳貽新
來源:
唐斌的博客