Track Image Loading效果代码分析

目的
在图片的加载过程中,提供定义图片加载成功或加载失败/超时时的回调函数,并确保执行。

动机
原生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>

(0)

相关推荐

  • javascript制作loading动画效果 loading效果

    复制代码 代码如下: /*ajax提交的延时等待效果*/ var AjaxLoding = new Object(); //wraperid : 显示loding图片的容器元素//ms:表示loding图标显示的时长,毫秒//envent:表示出发事件的事件源对象,用于获得出发事件的对象//callback:表示动画结束后执行的回掉方法//stop()方法表示在回掉方法执行成功后执行的隐藏动画的操作AjaxLoding.load = function(lodingid,ms,event,left

  • javascript 通用loading动画效果实例代码

    由于项目中多处要给ajax提交的时候增加等待动画效果,所以就写了一个简单的通用js方法:代码如下: 复制代码 代码如下: /*ajax提交的延时等待效果*/ var AjaxLoding = new Object(); //wraperid : 显示loding图片的容器元素//ms:表示loding图标显示的时长,毫秒//envent:表示出发事件的事件源对象,用于获得出发事件的对象//callback:表示动画结束后执行的回掉方法//stop()方法表示在回掉方法执行成功后执行的隐藏动画的操

  • JS 非图片动态loading效果实现代码

    代码如下: 首先实现该功能的js对象LoadingMsg: 复制代码 代码如下: var Class = { create: function() { return function() { this.init.apply(this,arguments); } } } var LoadingMsg = Class.create(); LoadingMsg.prototype = { init: function(spanId, spanMsg) { this.intervalID = -1000

  • 很酷的javascript loading效果代码

    复制代码 代码如下: <font color=red><script language="JavaScript">  <!--  var url = 'http://www.jb51.net'; ///这里是你的网址   //-->  </script>  </head>  <body onLoad="location.href = url">  <div style='margin-to

  • 一个仿DOS的Loading效果

    2500)){ clearTimeout(tid); //NS浏览器,指向code.htm,可以自己修改: if (document.layers){ top.location.href="http://www.pcedu.com.cn" } //IE浏览器,指向code.htm,可以自己修改: if (document.all){ top.location.href="http://www.pcedu.com.cn" } } } //其他浏览器,指向code.ht

  • 基于jquery的loading效果实现代码

    在代码<head></head>里加入以下代码: <script type="text/javascript" src="jquery.js"></script><script type="text/javascript">$(window).load(function(){$("#loading").hide();})</script> 在里<bo

  • Track Image Loading效果代码分析

    目的 在图片的加载过程中,提供定义图片加载成功或加载失败/超时时的回调函数,并确保执行. 动机 原生JavaScript已经对 Image 对象提供了 onload 和 onerror 注册事件.但在浏览器缓存及其他因素的影响下,用户在使用回退按钮或者刷新页面时 onload 事件常常未能稳定触发.在我开发的相册系统中,我希望图片能根据自定义的大小显示以免导致页面变形,例如最宽不得超过500px,而小于500px宽度的图片则按原大小显示.CSS2 提供了 max-width 属性能够帮组我们实现

  • JS基于Ajax实现的网页Loading效果代码

    本文实例讲述了JS基于Ajax实现的网页Loading效果代码.分享给大家供大家参考,具体如下: 这是一款很不错的网页Loading效果,常用于Ajax交互式网页设计中,点击按钮即可弹出Loading框,若Loading框未加载完成时关闭网页,会弹出确认提示框,用于一些对安全性能要求高的网页交互处理中,比如付款操作. 运行效果截图如下: 在线演示地址如下: http://demo.jb51.net/js/2015/js-ajax-web-loading-style-codes/ 具体代码如下:

  • JavaScript实现弹窗效果代码分析

    效果图: 话不多说,请看代码: 每个弹窗的标识 var x =0; var idzt = new Array(); var Window = function(config){ ID不重复 idzt[x] = "zhuti"+x; 弹窗ID 初始化,接收参数 this.config = { width : config.width || 300, 宽度 height : config.height || 200, 高度 buttons : config.buttons || '', 默

  • 基于mootools 1.3框架下的图片滑动效果代码

    效果预览如下: 实现原理: 容器采用相对定位,图片采用绝对定位,当鼠标移动到相应的图片上,改变去left属性,用tween实现动画效果. 代码分析:写一个picSlider类实现代码封装 复制代码 代码如下: <div id="container"> <img src="http://files.jb51.net/file_images/article/201104/r_song1.jpg" alt="" /> <i

  • Ajax全局加载框(Loading效果)的配置

    在Ajax进行后台数据请求的过程中,我们有时候会希望用户能知道页面后台还在做一些事情,这时候就需要给用户一个非常明确的提示,也就是我们所谓的进度条 实现原理: Jquery可以对ajax进行全局的设置,实现类似于C#中面向切面的效果,即对在Ajax提交之前和提交完成之后,我们均可以对其进行一系列的操作,所以我们可以在ajax开始的时候,把Loading框显示出来,在ajax请求完成之后,把loading框关闭掉,基本上就完美实现这个效果了. Jquery全局配置Ajax的方式为: $.ajaxS

  • 基于jquery实现的上传图片及图片大小验证、图片预览效果代码

    jquery实现上传图片及图片大小验证.图片预览效果代码 上传图片验证 复制代码 代码如下: */ function submit_upload_picture(){ var file = $('file_c').value; if(!/.(gif|jpg|jpeg|png|gif|jpg|png)$/.test(file)){ alert("图片类型必须是.gif,jpeg,jpg,png中的一种") }else{ $('both_form').action="file!u

  • jQuery实现的简单折叠菜单(折叠面板)效果代码

    本文实例讲述了jQuery实现的简单折叠菜单(折叠面板)效果代码.分享给大家供大家参考.具体如下: 这是一款基于jQuery实现的折叠菜单,可展开一些内容,实际上称它为一个面板比较好,是一个折叠面板,使用了jQuery1.6.2插件. 运行效果截图如下: 在线演示地址如下: http://demo.jb51.net/js/2015/jquery-simple-toggle-zd-menu-codes/ 具体代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD X

  • vue实现ajax滚动下拉加载,同时具有loading效果(推荐)

    代码如下所示: <!doctype html> <html> <head> <meta charset="utf-8"> <title>vue测试ajax的使用</title> <meta id="viewport" name="viewport" content="width=device-width, initial-scale=1.0, minimum-

随机推荐