作家
登录

Track Image Loading效果代码分析

作者: 来源:www.28hudong.com 2013-03-30 03:21:19 阅读 我要评论

目的 在图片的加载过程中,提供定义图片加载成功或加载失败/超时时的回调函数,并确保执行。 动机 原生JavaScript已经对 Image 对象提供了 onload 和 onerror 注册事件。但在浏览器缓存及其他因素的影响下,用户在使用回退按钮或者刷新页面时 onload 事件常常未能稳定触发。在我开发的相册系统中,我希望图片能根据自定义的大小显示以免导致页面变形,例如最宽不得超过500px,而小于500px宽度的图片则按原大小显示。CSS2 提供了 max-width 属性能够帮组我们实现这一目的。但很遗憾,挨千刀的IE6并不支持。 IE6一个弥补的办法就是通过注册 img.onload 事件,待图片加载完成后自动调整大小。以下代码取自著名的Discuz!论坛系统4.1版本对显示图片的处理。 <img src="http://img8.imagepile.net/img8/47104p155.jpg" border="0" onload="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new windownCTRL+Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new windownCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open('http://img8.imagepile.net/img8/47104p155.jpg');}" onmousewheel="return imgzoom(this);"> 前文已述,浏览器并不保证事件处理函数执行。所以需要一个更稳定的方式跟踪图片加载过程,并执行设定的回调函数。 实现 image.complete 属性标示的是图片加载状态,其值如果为ture,则表示加载成功。图片不存在或加载超时则值为false。利用 setInterval() 函数定时检查该状态则可以实现跟踪图片加载的状况。代码片断如下: ImageLoader = Class.create(); ImageLoader.prototype = { initialize : function(options) { this.options = Object.extend({ timeout: 60, //60s onInit: Prototype.emptyFunction, onLoad: Prototype.emptyFunction, onError: Prototype.emptyFunction }, options || {}); this.images = []; this.pe = new PeriodicalExecuter(this._load.bind(this), 0.02); }, ........ } 利用Prototype 的PeriodicalExecuter类创建一个定时器,每隔20毫秒检查一次图片的加载情况,并根据状态执行 options 参数中定义的回调函数。 使用 var loader = new ImageLoader({ timeout: 30, onInit: function(img) { img.style.width = '100px'; }, onLoad: function(img) { img.style.width = ''; if (img.width > 500) img.style.width = '500px'; }, onError: function(img) { img.src = 'error.jpg'; //hint image } });loader.loadImage(document.getElementsByTagName('img')); 上面的代码定义图片最初以100px显示,加载成功后如果图片实际宽度超过500px,则再强制定义为500px,否则显示原大小。如果图片不存在或加载超时(30秒为超时),则显示错误图片。 同理,可以应用 ImageLoader 的回调函数来根据需求自定义效果,例如默认显示loading,加载完成后再显示原图;图片首先灰度显示,加载完成后再恢复亮度等等。例如: //need scriptaculous effects.js var loader = new ImageLoader({ onInit: function(img) { Element.setOpacity(img, 0.5); //默认5级透明 }, onLoad: function(img) { Effect.Appear(img); //恢复原图显示 } }); 附示例中包含完整的代码及使用pconline图片为例的测试, 注意 范例中使用了最新的Prototype 1.5.0_rc1。 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 //EN"> <html> <head> <script src="prototype1.5.0_rc1.js"></script> <script src="validation1.5.3/effects.js"></script> </head> <body> <img id="img0" src="http://img.pconline.com.cn/images/photoblog/2026024/20069/14/1158169144171.jpg" /> <img id="img1" src="http://img.pconline.com.cn/images/photoblog/2026024/20069/14/1158169158366.jpg" /> <img id="img2" src="http://img.pconline.com.cn/images/photoblog/2026024/20069/14/1158169169983_mthumb.jpg" /> <br />加载失败测试<br /> <img id="img2" src="http://img.pconline.com.cn/images/photoblog/2026024/20069/14/000000000000.jpg" /> <script type="text/javascript"> ImageLoader = Class.create(); ImageLoader.prototype = { initialize : function(options) { this.options = Object.extend({ timeout: 60, //60s onInit: Prototype.emptyFunction, onLoad: Prototype.emptyFunction, onError: Prototype.emptyFunction }, options || {}); this.images = []; this.pe = new PeriodicalExecuter(this._load.bind(this), 0.02); }, loadImage : function() { var self = this; $A(arguments).each(function(img) { if (typeof(img) == 'object') $A(img).each(self._addImage.bind(self)); else self._addImage(img); }); }, _addImage : function(img) { img = $(img); img.onerror = this._onerror.bind(this, img); this.options.onInit.call(this, img); if (this.options.timeout > 0) { setTimeout(this._ontimeout.bind(this, img), this.options.timeout*1000); } this.images.push(img); if (!this.pe.timer) this.pe.registerCallback(); }, _load: function() { this.images = this.images.select(this._onload.bind(this)); if (this.images.length == 0) { this.pe.stop(); } }, _checkComplete : function(img) { if (img._error) { return true; } else { return img.complete; } }, _onload : function(img) { if (this._checkComplete(img)) { this.options.onLoad.call(this, img); img.onerror = null; if (img._error) try {delete img._error}catch(e){} return false; } return true; }, _onerror : function(img) { img._error = true; img.onerror = null; this.options.onError.call(this, img); }, _ontimeout : function(img) { if (!this._checkComplete(img)) { this._onerror(img); } } } var loader = new ImageLoader({ timeout: 30, onInit: function(img) { img.style.width = '100px'; }, onLoad: function(img) { img.style.width = ''; if (img.width > 500) { img.style.width = '500px'; } }, onError: function(img) { img.src = 'http://img.pconline.com.cn/nopic.gif'; } }); loader.loadImage(document.getElementsByTagName('img')); /* var loader = new ImageLoader({ timeout: 30, onInit: function(img) { Element.setOpacity(img, 0.5); }, onLoad: function(img) { Effect.Appear(img); }, onError: function(img) { img.src = 'http://img.pconline.com.cn/nopic.gif'; } }); */ /* $A(document.getElementsByTagName('img')).each( function(img) { img.onload = function() { img.style.width = '300px'; } } ); */ </script> </body> </html>

  推荐阅读

  推荐一个小巧的JS日历

脚本的核心就是DateAdd函数,点击下面的演示看看效果: 查看演示 调用方法很简单, 第一步:在页面顶部包含calenderJS.js文件: <script src="path/to/calenderJS.js"></script> 点击下载这个js文件 第二步:给你>>>详细阅读


本文标题:Track Image Loading效果代码分析

地址:http://www.17bianji.com/kaifa2/JS/30213.html

关键词: 探索发现

乐购科技部分新闻及文章转载自互联网,供读者交流和学习,若有涉及作者版权等问题请及时与我们联系,以便更正、删除或按规定办理。感谢所有提供资讯的网站,欢迎各类媒体与乐购科技进行文章共享合作。

网友点评
自媒体专栏

评论

热度

精彩导读
栏目ID=71的表不存在(操作类型=0)