JS最全的图片预加载技术并且封装成插件

来源:互联网 发布:淘宝怎么做手机上 编辑:程序博客网 时间:2024/06/14 22:38

图片预加载-顶部滚动条形式

<!DOCTYPE html><html><head><meta charset="utf-8" /><title>图片预加载顶部滚动条形式</title><style>html,body,p {margin: 0;padding: 0;}.load {height: 5px;font-size: 12px;background: #109874;text-align: center;color: #ddd;position: fixed;left: 0;top: 0;}img {display: block;margin-bottom: 10px;width: 100%;}</style></head><body><div id="load" class="load"></div><script>function Loading() {this.init.apply(this, arguments); //参数arguments =[0:"load",1:Array(4),2:f (aImg)]}//object.prototype.name=value 向对象添加属性和方法。Loading.prototype.init = function(id, aImg, handler) {var oCon = document.getElementById(id),aData = [],iImgCount = 0,iLoaded = 0;if(!oCon) {return;}for(var i = 0, iImgCount = aImg.length; i < iImgCount; i++) {var oImg = new Image();//后执行oImg.onload = function() { oCon.style.width = Math.round((iLoaded+1) / iImgCount * 100) + "%";var aTmp = document.createElement("img");aTmp.src = this.src;aData.push(aTmp);if(aData.length == iImgCount) {handler(aData);} iLoaded++;} oImg.src = aImg[i]; //先执行 }}var aImg = ["http://pic1.win4000.com/wallpaper/f/5427b8a07aa3c.jpg","http://pic1.win4000.com/wallpaper/0/543b6f51e59b0.jpg","http://pic1.win4000.com/wallpaper/f/5427b8a07aa3c.jpg","http://pic1.win4000.com/wallpaper/0/543b6f51e59b0.jpg"];new Loading("load", aImg, function(aImg) {var frag = document.createDocumentFragment();for(var i = 0; i < aImg.length; i++) {frag.appendChild(aImg[i]);}document.body.appendChild(frag);});</script></body></html>
扩展:document的createDocumentFragment()方法
在更新少量节点的时候可以直接向document.body节点中添加,但是当要向document中添加大量数据时,如果直接添加这些新节点,这个过程非常缓慢,因为每添加一个节点都会调用父节点的appendChild()方法,为了解决这个问题,可以创建一个文档碎片,把所有的新节点附加其上,然后把文档碎片一次性添加到document中。
假如想创建十个段落,使用常规的方式可能会写出这样的代码:
for(var i = 0; i < 10; i++) {var p = document.createElement("p");var oTxt = document.createTextNode("段落" + i);p.appendChild(oTxt);document.body.appendChild(p);}
当然,这段代码运行是没有问题,但是他调用了十次document.body.appendChild(),每次都要产生一次页面渲染。这时碎片就十分有用了:
var oFragment = document.createDocumentFragment();for(var i = 0; i < 10; i++) {var p = document.createElement("p");var oTxt = document.createTextNode("段落" + i);p.appendChild(oTxt);oFragment.appendChild(p);}document.body.appendChild(oFragment);
在这段代码中,每个新的<p />元素都被添加到文档碎片中,然后这个碎片被作为参数传递给appendChild()。这里对appendChild()的调用实际上并不是把文档碎片本省追加到body元素中,而是仅仅追加碎片中的子节点,然后可以看到明显的性能提升,document.body.appenChild()一次替代十次,这意味着只需要进行一个内容渲染刷新。

图片预加载-无序加载

<!DOCTYPE html><html lang="zh-CN"><head><meta charset="utf-8" /><title>图片预加载-无序加载</title><style>html,body {height: 100%;}a {text-decoration: none;}.box {text-align: center;}.btn {display: inline-block;height: 30px;line-height: 30px;border: 1px solid #ccc;background-color: #fff;padding: 0 10px;margin-right: 50px;color: #333;}.btn:hover {background-color: #eee;}.loading {position: fixed;top: 0;left: 0;width: 100%;height: 100%;background-color: #eee;text-align: center;font-size: 30px;}.progress {margin-top: 300px;}</style></head><body><div class="box"><img src="http://pic1.win4000.com/wallpaper/f/5427b8a07aa3c.jpg" id="img" width="1200" /><p><a href="javascript:;" class="btn" data-control="prev">上一页</a><a href="javascript:;" class="btn" data-control="next">下一页</a></p></div><div class="loading"><p class="progress">0%</p></div><script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script><script type="text/javascript" src="preload.js"></script><script>//图片资源var imgs = ["http://pic1.win4000.com/wallpaper/f/5427b8a07aa3c.jpg","http://pic1.win4000.com/wallpaper/0/543b6f51e59b0.jpg","http://pic1.win4000.com/wallpaper/f/5427b8a07aa3c.jpg","http://pic1.win4000.com/wallpaper/0/543b6f51e59b0.jpg"];var index = 0,len = imgs.length,$progress = $('.progress');    //上下切换$('.btn').on('click', function() {if($(this).data('control') === 'prev') {index = Math.max(0, --index);} else {index = Math.min(len - 1, ++index);}document.title = (index + 1) + '/' + len;$('#img').attr('src', imgs[index]);});//图片加载(此处封装成插件的形式)$.preload(imgs, {each: function(count) {$progress.html(Math.round((count + 1) / len * 100) + '%');},all: function() {$('.loading').hide();document.title = '1/' + len;}})</script></body></html>

图片预加载-无序加载QQ

<!DOCTYPE html><html lang="zh-CN"><head><meta charset="utf-8" /><title>图片预加载-无序加载QQ</title><style>html,body {height: 100%;}body,p,ul,li {padding: 0;margin: 0;}body {background-color: #eee;}.box {margin: 150px 0 0 200px;}#face-btn {display: block;color: #333;}a {text-decoration: none;}li {list-style-type: none;}.panel {display: none;width: 600px;padding: 2px;border: 1px solid #ccc;background-color: #fff;}.loading {text-align: center;}.list li {display: inline-block;width: 100px;height: 70px;border: 1px solid #fff;margin-bottom: 5px;cursor: pointer;}.list li img {width: 100%;}.list li:hover {border-color: #06c;}</style></head><body><div class="box"><a href="javascript:;" id="face-btn">打开表情</a><div class="panel"><p class="loading">表情加载中,请稍后。。。</p></div></div><script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script><script type="text/javascript" src="preload.js"></script><script>var btn = $('#face-btn'),panel = $('.panel');var imgs = ['http://qq.yh31.com/tp/zr/zr240.gif', 'http://qq.yh31.com/tp/zr/zr240.gif', 'http://qq.yh31.com/tp/zr/zr240.gif', 'http://qq.yh31.com/tp/zr/zr240.gif','http://qq.yh31.com/tp/zr/zr240.gif', 'http://qq.yh31.com/tp/zr/zr240.gif','http://qq.yh31.com/tp/zr/zr240.gif', 'http://qq.yh31.com/tp/zr/zr240.gif', 'http://qq.yh31.com/tp/zr/zr240.gif', 'http://qq.yh31.com/tp/zr/zr240.gif', 'http://qq.yh31.com/tp/zr/zr240.gif', 'http://qq.yh31.com/tp/zr/zr240.gif'];var len = imgs.length;btn.on('click', function(e) {//阻止事件冒泡e.stopPropagation();panel.show();$.preload(imgs, {all: function() {var html = '<ul class="list">';for(var i = 0; i < len; i++) {html += '<li><img src="' + imgs[i] + '" alt="" /></li>';}html += '</ul>'; panel.html(html); }})});$(document).on('click', function() { panel.hide();})</script></body></html>

图片预加载-有序加载(试用于加载漫画之类按顺序排列的图片)

<!DOCTYPE html><html lang="zh-CN"><head><meta charset="utf-8" /><title>图片预加载-有序加载</title><style>a {text-decoration: none;}.box {text-align: center;}.btn {display: inline-block;height: 30px;line-height: 30px;border: 1px solid #ccc;background-color: #fff;padding: 0 10px;margin-right: 50px;color: #333;}.btn:hover {background-color: #eee;}</style></head><body><div class="box"><img src="http://45.34.137.202:8080/comicdata/12307/1/1.jpg" id="img" width="1200" /><p><a href="javascript:;" class="btn" data-control="prev">上一页</a><a href="javascript:;" class="btn" data-control="next">下一页</a></p></div><script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script><script type="text/javascript" src="preload.js"></script><script>var imgs = ['http://45.34.137.202:8080/comicdata/12307/1/1.jpg','http://45.34.137.202:8080/comicdata/12307/1/2.jpg','http://45.34.137.202:8080/comicdata/12307/1/3.jpg','http://45.34.137.202:8080/comicdata/12307/1/4.jpg','http://45.34.137.202:8080/comicdata/12307/1/5.jpg','http://45.34.137.202:8080/comicdata/12307/1/6.jpg','http://45.34.137.202:8080/comicdata/12307/1/7.jpg'];var len = imgs.length,index = 0,count = 0;//有序预加载$.preload(imgs, {order: 'ordered'})  $('.btn').on('click', function() {if($(this).data('control') === 'prev') {index = Math.max(0, --index);} else {index = Math.min(len - 1, ++index);}document.title = (index + 1) + '/' + len;$('#img').attr('src', imgs[index]);});</script></body></html>

封装成插件形式的preload.js

(function($) {function PreLoad(imgs, options) {//判断是否是一张图片,并且写成字符串的形式this.imgs = (typeof imgs === 'string') ? [imgs] : imgs; //this = PreLoad//将后一个覆盖前一个的内容 返回新的对象this.opts = $.extend({}, PreLoad.DEFAULTS, options);//this.opts//无序加载QQ {order: "unordered", each: null, all: ƒ} //无序加载  {order: "unordered", each: ƒ, all: ƒ} //有序加载  {order: "ordered", each: null, all: null}  if(this.opts.order === "ordered") {this.ordered();} else {this.unordered();}}PreLoad.DEFAULTS = {order: 'unordered', //无序预加载each: null, //每张图片加载完毕后执行all: null //所有图片加载完后执行};//无序加载PreLoad.prototype.unordered = function() {var imgs = this.imgs,opts = this.opts,count = 0,len = imgs.length;$.each(imgs, function(i, item) {if(typeof item != 'string') {return;}var imgObj = new Image();$(imgObj).on('load error', function() { //先判断 each是不是存在,如果存在就执行,这样写的目的是为了防止报错 如果直接写 each(),当each不存在时代码就会报错。opts.each && opts.each(count);if(count >= len - 1) {opts.all && opts.all();} count++;}); imgObj.src = item; });};//有序加载PreLoad.prototype.ordered = function() {var opts = this.opts,imgs = this.imgs,len = imgs.length,count = 0;    load();function load() {var imgObj = new Image();$(imgObj).on('load error', function() {if(count >= len) {//所有图片已经加载完毕 alert("所有图片已经加载完毕");} else {    load();}count++;});imgObj.src = imgs[count];}}$.extend({preload: function(imgs, opts) {new PreLoad(imgs, opts);}});})(jQuery);

欢迎大家拍砖!!