imgready.js 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. // 更新:
  2. // 05.27: 1、保证回调执行顺序:error > ready > load;2、回调函数this指向img本身
  3. // 04-02: 1、增加图片完全加载后的回调 2、提高性能
  4. /**
  5. * 图片头数据加载就绪事件 - 更快获取图片尺寸
  6. * @version 2011.05.27
  7. * @author TangBin
  8. * @see http://www.planeart.cn/?p=1121
  9. * @param {String} 图片路径
  10. * @param {Function} 尺寸就绪
  11. * @param {Function} 加载完毕 (可选)
  12. * @param {Function} 加载错误 (可选)
  13. * @example imgReady('http://www.google.com.hk/intl/zh-CN/images/logo_cn.png', function () {
  14. alert('size ready: width=' + this.width + '; height=' + this.height);
  15. });
  16. */
  17. var imgReady = (function () {
  18. var list = [], intervalId = null,
  19. // 用来执行队列
  20. tick = function () {
  21. var i = 0;
  22. for (; i < list.length; i++) {
  23. list[i].end ? list.splice(i--, 1) : list[i]();
  24. };
  25. !list.length && stop();
  26. },
  27. // 停止所有定时器队列
  28. stop = function () {
  29. clearInterval(intervalId);
  30. intervalId = null;
  31. };
  32. return function (url, ready, load, error) {
  33. var onready, width, height, newWidth, newHeight,
  34. img = new Image();
  35. img.src = url;
  36. // 如果图片被缓存,则直接返回缓存数据
  37. if (img.complete) {
  38. ready.call(img);
  39. load && load.call(img);
  40. return;
  41. };
  42. width = img.width;
  43. height = img.height;
  44. // 加载错误后的事件
  45. img.onerror = function () {
  46. error && error.call(img);
  47. onready.end = true;
  48. img = img.onload = img.onerror = null;
  49. };
  50. // 图片尺寸就绪
  51. onready = function () {
  52. newWidth = img.width;
  53. newHeight = img.height;
  54. if (newWidth !== width || newHeight !== height ||
  55. // 如果图片已经在其他地方加载可使用面积检测
  56. newWidth * newHeight > 1024
  57. ) {
  58. ready.call(img);
  59. onready.end = true;
  60. };
  61. };
  62. onready();
  63. // 完全加载完毕的事件
  64. img.onload = function () {
  65. // onload在定时器时间差范围内可能比onready快
  66. // 这里进行检查并保证onready优先执行
  67. !onready.end && onready();
  68. load && load.call(img);
  69. // IE gif动画会循环执行onload,置空onload即可
  70. img = img.onload = img.onerror = null;
  71. };
  72. // 加入队列中定期执行
  73. if (!onready.end) {
  74. list.push(onready);
  75. // 无论何时只允许出现一个定时器,减少浏览器性能损耗
  76. if (intervalId === null) intervalId = setInterval(tick, 40);
  77. };
  78. };
  79. })();