模仿【http://www.otomate.jp/ghp/fd/】的图片预加载所写。该页使用jQuery,这里使用原生javascript。javascript
在ie6,ie8,FF,Chrome,Opera下测试经过。css
过程:java
一、在DOM树加载完毕时,将页面内全部图片(img标签,css中的背景图)的地址push进一个数组。web
二、用image图片加载完成触发的load事件进行回调,显示当前进度。【已加载完图片数/总图片数】正则表达式
三、图片所有加载完毕,进行以后的处理。(如上述url页所示,将遮罩层移除)编程
关键点:数组
javascript一般采用非阻塞式(异步)编程,故而没法顺次加载图片。浏览器
所以必须在每张图片加载完后触发一个回调函数,在回调函数中判断是否所有加载完毕。缓存
相关代码步骤:异步
一、DOM树加载完毕的事件(jQuery的docuiment ready)
window.onload会在全部资源加载完毕后触发,故而不能使用。
大部分现代浏览器支持DOMContentLoaded事件【webkit525版本如下(safari 3.1如下)不支持,这里不做考虑】;
IE支持readystatechange事件,监听document.readyState属性为【interactive】或【complete】时便可认为加载完毕。
相关代码以下,以《JS高级程序设计》为参考,并做了处理防止重复判断是IE仍是现代浏览器。
1 CCC.documentReady = function(f){ 2 if( document.addEventListener ) { 3 CCC.documentReady = function(func){ 4 document.addEventListener('DOMContentLoaded', function(){ 5 document.removeEventListener('DOMContentLoaded', arguments.callee); 6 func(); 7 }, false); 8 }; 9 } else { 10 CCC.documentReady = function(func){ 11 document.attachEvent('onreadystatechange', function(){ 12 if (document.readyState == 'interactive' || document.readyState == 'complete') { 13 document.detachEvent('onreadystatechange', arguments.callee); 14 func(); 15 } 16 }); 17 }; 18 } 19 CCC.documentReady(f); 20 };
二、获取图片url
getStyle为一个获取计算后样式的方法,作了兼容。
各浏览器获取到的background-image属性,格式为【url(...)】,可能包含双引号【url("...")】,所以正则表达式须要考虑到这些状况。
bg.replace(/url\("?([^"]+)"?\)/, '$1');
var all = document.body.getElementsByTagName('*'); var imgUrls = []; for(var i = 0, len = all.length; i < len; i++) { if(all[i].tagName.toLowerCase() == 'img') { if(all[i].src) { imgUrls.push(all[i].src); } } else { var bg = _(all[i]).getStyle('background-image'); if(/url/.test(bg)) { bg = bg.replace(/url\("?([^"]+)"?\)/, '$1'); imgUrls.push(bg); } } }
三、preload预加载函数
经过对Image对象设置src属性来加载图片。
如在浏览器中已有缓存,则直接回调;不然添加onload事件处理函数,异步回调。
complete为当前已加载完毕的图片数。
function preload(arr, callback){ var complete = 0; for(var i = 0, len = arr.length; i < len; i++) { var img = new Image(); img.src = arr[i];; if(img.complete) { /* 已缓存 */ callback(++complete, len); continue; } img.onload = function(){ callback(++complete, len); }; } }
四、使用preload函数
在回调方法中,使用一个input标签显示当前进度;
当所有加载完毕(经过complete >= len来判断),进行最后的处理。这里仅仅是简单的alert。
preload(imgUrls, function(complete, len){ if(complete >= len) { progress.value = '100%'; imgUrls = null; alert('complete'); return; } progress.value = parseInt(complete * 100 / len) + '%'; });
以上简陋代码仅做我的思路记录,