利用CSS、JavaScript及Ajax实现高效的图片预加载


Posted in Javascript onOctober 16, 2013

方法一:用CSS和JavaScript实现预加载

实现预加载图片有很多方法,包括使用CSS、JavaScript及两者的各种组合。这些技术可根据不同设计场景设计出相应的解决方案,十分高效。
单纯使用CSS,可容易、高效地预加载图片,代码如下:

#preload-01 { background: url(http://domain.tld/image-01.png) no-repeat -9999px -9999px; } 
#preload-02 { background: url(http://domain.tld/image-02.png) no-repeat -9999px -9999px; } 
#preload-03 { background: url(http://domain.tld/image-03.png) no-repeat -9999px -9999px; }

将这三个ID选择器应用到(X)HTML元素中,我们便可通过CSS的background属性将图片预加载到屏幕外的背景上。只要这些图片的路径保持不变,当它们在Web页面的其他地方被调用时,浏览器就会在渲染过程中使用预加载(缓存)的图片。简单、高效,不需要任何JavaScript。
该方法虽然高效,但仍有改进余地。使用该法加载的图片会同页面的其他内容一起加载,增加了页面的整体加载时间。为了解决这个问题,我们增加了一些JavaScript代码,来推迟预加载的时间,直到页面加载完毕。代码如下:
// better image preloading @ <a href="http://perishablepress.com/press/2009/12/28/3-ways-preload-images-css-javascript-ajax/">http://perishablepress.com/press/2009/12/28/3-ways-preload-images-css-javascript-ajax/</a> 
function preloader() { 
if (document.getElementById) { 
document.getElementById("preload-01").style.background = "url(http://domain.tld/image-01.png) no-repeat -9999px -9999px"; 
document.getElementById("preload-02").style.background = "url(http://domain.tld/image-02.png) no-repeat -9999px -9999px"; 
document.getElementById("preload-03").style.background = "url(http://domain.tld/image-03.png) no-repeat -9999px -9999px"; 
} 
} 
function addLoadEvent(func) { 
var oldonload = window.onload; 
if (typeof window.onload != 'function') { 
window.onload = func; 
} else { 
window.onload = function() { 
if (oldonload) { 
oldonload(); 
} 
func(); 
} 
} 
} 
addLoadEvent(preloader);

在该脚本的第一部分,我们获取使用类选择器的元素,并为其设置了background属性,以预加载不同的图片。
该脚本的第二部分,我们使用addLoadEvent()函数来延迟preloader()函数的加载时间,直到页面加载完毕。
如果JavaScript无法在用户的浏览器中正常运行,会发生什么?很简单,图片不会被预加载,当页面调用图片时,正常显示即可。

方法二:仅使用JavaScript实现预加载

上述方法有时确实很高效,但我们逐渐发现它在实际实现过程中会耗费太多时间。相反,我更喜欢使用纯JavaScript来实现图片的预加载。下面将提供两种这样的预加载方法,它们可以很漂亮地工作于所有现代浏览器之上。

JavaScript代码段1

只需简单编辑、加载所需要图片的路径与名称即可,很容易实现:

<div class="hidden"> 
<script type="text/javascript"> 
<!--//--><![CDATA[//><!-- 
var images = new Array() 
function preload() { 
for (i = 0; i < preload.arguments.length; i++) { 
images[i] = new Image() 
images[i].src = preload.arguments[i] 
} 
} 
preload( 
"http://domain.tld/gallery/image-001.jpg", 
"http://domain.tld/gallery/image-002.jpg", 
"http://domain.tld/gallery/image-003.jpg" 
) 
//--><!]]> 
</script> 
</div>

该方法尤其适用预加载大量的图片。我的画廊网站使用该技术,预加载图片数量达50多张。将该脚本应用到登录页面,只要用户输入登录帐号,大部分画廊图片将被预加载。

JavaScript代码段2

该方法与上面的方法类似,也可以预加载任意数量的图片。将下面的脚本添加入任何Web页中,根据程序指令进行编辑即可。

<div class="hidden"> 
<script type="text/javascript"> 
<!--//--><![CDATA[//><!-- 
if (document.images) { 
img1 = new Image(); 
img2 = new Image(); 
img3 = new Image(); 
img1.src = "http://domain.tld/path/to/image-001.gif"; 
img2.src = "http://domain.tld/path/to/image-002.gif"; 
img3.src = "http://domain.tld/path/to/image-003.gif"; 
} 
//--><!]]> 
</script> 
</div>

正如所看见,每加载一个图片都需要创建一个变量,如“img1 = new Image();”,及图片源地址声明,如“img3.src = "../path/to/image-003.gif";”。参考该模式,你可根据需要加载任意多的图片。
我们又对该方法进行了改进。将该脚本封装入一个函数中,并使用 addLoadEvent(),延迟预加载时间,直到页面加载完毕。
function preloader() { 
if (document.images) { 
var img1 = new Image(); 
var img2 = new Image(); 
var img3 = new Image(); 
img1.src = "http://domain.tld/path/to/image-001.gif"; 
img2.src = "http://domain.tld/path/to/image-002.gif"; 
img3.src = "http://domain.tld/path/to/image-003.gif"; 
} 
} 
function addLoadEvent(func) { 
var oldonload = window.onload; 
if (typeof window.onload != 'function') { 
window.onload = func; 
} else { 
window.onload = function() { 
if (oldonload) { 
oldonload(); 
} 
func(); 
} 
} 
} 
addLoadEvent(preloader);

方法三:使用Ajax实现预加载

上面所给出的方法似乎不够酷,那现在来看一个使用Ajax实现图片预加载的方法。该方法利用DOM,不仅仅预加载图片,还会预加载CSS、JavaScript等相关的东西。使用Ajax,比直接使用JavaScript,优越之处在于JavaScript和CSS的加载不会影响到当前页面。该方法简洁、高效。

window.onload = function() { 
setTimeout(function() { 
// XHR to request a JS and a CSS 
var xhr = new XMLHttpRequest(); 
xhr.open('GET', 'http://domain.tld/preload.js'); 
xhr.send(''); 
xhr = new XMLHttpRequest(); 
xhr.open('GET', 'http://domain.tld/preload.css'); 
xhr.send(''); 
// preload image 
new Image().src = "http://domain.tld/preload.png"; 
}, 1000); 
};

上面代码预加载了“preload.js”、“preload.css”和“preload.png”。1000毫秒的超时是为了防止脚本挂起,而导致正常页面出现功能问题。
下面,我们看看如何用JavaScript来实现该加载过程:
window.onload = function() { 
setTimeout(function() { 
// reference to <head> 
var head = document.getElementsByTagName('head')[0]; 
// a new CSS 
var css = document.createElement('link'); 
css.type = "text/css"; 
css.rel = "stylesheet"; 
css.href = "http://domain.tld/preload.css"; 
// a new JS 
var js = document.createElement("script"); 
js.type = "text/javascript"; 
js.src = "http://domain.tld/preload.js"; 
// preload JS and CSS 
head.appendChild(css); 
head.appendChild(js); 
// preload image 
new Image().src = "http://domain.tld/preload.png"; 
}, 1000); 
};

这里,我们通过DOM创建三个元素来实现三个文件的预加载。正如上面提到的那样,使用Ajax,加载文件不会应用到加载页面上。从这点上看,Ajax方法优越于JavaScript。
Javascript 相关文章推荐
用JS写的一个TableView控件代码
Jan 23 Javascript
JavaScript格式化数字的函数代码
Nov 30 Javascript
javascript页面渲染速度测试脚本分享
Apr 15 Javascript
Node.js中的流(Stream)介绍
Mar 30 Javascript
js完美解决IE6不支持position:fixed的bug
Apr 24 Javascript
JavaScript实现Base64编码转换
Apr 23 Javascript
基于BootStrap Metronic开发框架经验小结【二】列表分页处理和插件JSTree的使用
May 12 Javascript
原生JS版和jquery版实现checkbox的全选/全不选/点选/行内点选(Mr.Think)
Oct 29 Javascript
Vue.js组件通信的几种姿势
Oct 23 Javascript
详解webpack-dev-server的简单使用
Apr 02 Javascript
ZK中使用JS读取客户端txt文件内容问题
Nov 07 Javascript
javascript设计模式 ? 适配器模式原理与应用实例分析
Apr 13 Javascript
div模拟滚动条效果示例代码
Oct 16 #Javascript
Jquery实现的tab效果可以指定默认显示第几页
Oct 16 #Javascript
jQuery实现等比例缩放大图片让大图片自适应页面布局
Oct 16 #Javascript
限制textbox或textarea输入字符长度的JS代码
Oct 16 #Javascript
父元素与子iframe相互获取变量和元素对象的具体实现
Oct 15 #Javascript
纯Javascript实现Windows 8 Metro风格实现
Oct 15 #Javascript
自定义ExtJS控件之下拉树和下拉表格附源码
Oct 15 #Javascript
You might like
php下封装较好的数字分页方法
2010/11/23 PHP
file_get_contents(&quot;php://input&quot;, &quot;r&quot;)实例介绍
2013/07/01 PHP
php后台如何避免用户直接进入方法实例
2013/10/15 PHP
PHP Callable强制指定回调类型的方法
2016/08/30 PHP
Zend Framework框架实现类似Google搜索分页效果
2016/11/25 PHP
PHP框架实现WebSocket在线聊天通讯系统
2019/11/21 PHP
如何在Web页面上直接打开、编辑、创建Office文档
2007/03/12 Javascript
返回对象在当前级别中是第几个元素的实现代码
2011/01/20 Javascript
DIV外区域Click后关闭DIV的实现代码
2011/12/21 Javascript
编写js扩展方法判断一个数组中是否包含某个元素
2013/11/08 Javascript
javascript和jquery修改a标签的href属性
2013/12/16 Javascript
Javascript的表单与验证-非空验证
2016/03/18 Javascript
jQuery实现表格行和列的动态添加与删除方法【测试可用】
2016/08/01 Javascript
JS百度地图搜索悬浮窗功能
2017/01/12 Javascript
jQuery自定义多选下拉框效果
2017/06/19 jQuery
深入探究AngularJs之$scope对象(作用域)
2017/07/20 Javascript
jquery 键盘事件的使用方法详解
2017/09/13 jQuery
Vuex 入门教程
2018/01/10 Javascript
详解ajax的data参数错误导致页面崩溃
2018/04/30 Javascript
详解在React中跨组件分发状态的三种方法
2018/08/09 Javascript
vue多次循环操作示例
2019/02/08 Javascript
使用Three.js实现太阳系八大行星的自转公转示例代码
2019/04/09 Javascript
跟老齐学Python之集合(set)
2014/09/24 Python
Python md5与sha1加密算法用法分析
2017/07/14 Python
给你选择Python语言实现机器学习算法的三大理由
2017/11/15 Python
Python 图像对比度增强的几种方法(小结)
2019/09/25 Python
使用IDLE的Python shell窗口实例详解
2019/11/19 Python
python实现梯度下降算法的实例详解
2020/08/17 Python
Python利用pip安装tar.gz格式的离线资源包
2020/09/14 Python
澳大利亚女装精品店:Alannah Hill
2020/07/29 全球购物
入党自我评价优缺点
2014/01/25 职场文书
大学军训感言300字
2014/03/09 职场文书
2015年学校政教工作总结
2015/07/20 职场文书
2016年综治和平安建设宣传月活动总结
2016/04/01 职场文书
go 原生http web 服务跨域restful api的写法介绍
2021/04/27 Golang
PostgreSQL数据库去除重复数据和运算符的基本查询操作
2022/04/12 PostgreSQL