autoIMG 基于jquery的图片自适应插件代码

  为了防止图片撑破布局,最常见的仍然是通过onload后获取图片尺寸再进行调整,所以加载过程中仍然会撑破。而Qzone日志的图片在此进行了改进,onload完毕后才显示原图。我以前用onload写过一个小例子:http://www.planeart.cn/?p=1022

  通过imgReady可以跨浏览器在dom ready就可以实现图片自适应,无需等待img加载,代码如下:

  

复制代码 代码如下:

  // jQuery.autoIMG.js v0.2

  // Tang Bin - http://planeArt.cn/ - MIT Licensed

  (function ($) {

  var // 设置加载状态的替换图像

  tempPath = './images/loading.png',

  // 设置加载错误的替换图像

  errorPath = './images/error.png',

  // 检测是否支持css2.1 max-width属性

  isMaxWidth = 'maxWidth' in document.documentElement.style,

  // 检测是否IE7浏览器

  isIE7 = !-[1,] && !('prototype' in Image) && isMaxWidth;

  new Image().src = tempPath;

  $.fn.autoIMG = function () {

  var $this = this,

  // 获取容器宽度

  maxWidth = $this.width();

  return $this.find('img').each(function (i, img) {

  // 如果支持max-width属性则使用此,否则使用下面预加载方式

  if (isMaxWidth) return img.style.maxWidth = maxWidth + 'px';

  var path = img.getAttribute('data-src') || img.src,

  next = img.nextSibling,

  parent = img.parentNode,

  temp = new Image();

  // 删除img图像,并替换成loading图片

  img.style.display = 'none';

  img.removeAttribute('src');

  img.parentNode.removeChild(img);

  temp.src = tempPath;

  next ? next.insertBefore(temp) : parent.appendChild(temp);

  // 图片尺寸就绪执行

  imgReady(path, function (width, height) {

  if (width > maxWidth) {

  // 等比例缩放

  height = maxWidth / width * height,

  width = maxWidth;

  // 删除loading图像

  temp.parentNode.removeChild(temp);

  // 恢复显示调整后的原图像

  img.style.display = '';

  img.style.width = width + 'px';

  img.style.height = height + 'px';

  img.setAttribute('src', path);

  next ? next.insertBefore(img) : parent.appendChild(img);

  };

  }, function () {

  // 加载错误

  temp.src = errorPath;

  temp.title = 'Image load error!';

  });

  });

  };

  // IE7缩放图片会失真,采用私有属性通过三次插值解决

  isIE7 && (function (c,d,s) {s=d.createElement('style');d.getElementsByTagName('head')[0].appendChild(s);s.styleSheet&&(s.styleSheet.cssText+=c)||s.appendChild(d.createTextNode(c))})('img {-ms-interpolation-mode:bicubic}',document);

  // 获取图片头的尺寸数据

  // http://www.planeart.cn/?p=1121

  // @param {String} 图片路径

  // @param {Function} 获取尺寸的回调函数 (参数1接收width;参数2接收height)

  // @param {Function} 加载错误的回调函数 (可选)

  var imgReady = function (url, callback, error) {

  var width, height, offsetWidth, offsetHeight, intervalId, check, div,

  accuracy = 1024,

  doc = document,

  container = doc.body || doc.getElementsByTagName('head')[0],

  img = new Image();

  img.src = url;

  // 如果图片被缓存,则直接返回缓存数据

  if (img.complete) {

  return callback(img.width, img.height);

  };

  // 向页面插入隐秘图像,监听图片尺寸就绪状态

  if (container) {

  div = doc.createElement('div');

  div.style.cssText = 'visibility:hidden;position:absolute;left:0;top:0;width:1px;height:1px;overflow:hidden';

  div.appendChild(img)

  container.appendChild(div);

  width = img.offsetWidth;

  height = img.offsetHeight;

  check = function () {

  offsetWidth = img.offsetWidth;

  offsetHeight = img.offsetHeight;

  // 如果图像尺寸开始变化,则表示浏览器已经获取了图片头数据并占位

  // 经过实测只有监听img.offsetWidth才有效,同时检测img.offsetHeight是为了保险

  // 如果新插入的图片面积大于预设尺寸,很可能是执行前图片以及在其他地方加载中,如基于webkit的浏览器

  if (offsetWidth !== width || offsetHeight !== height || offsetWidth * offsetHeight > accuracy) {

  clearInterval(intervalId);

  callback(offsetWidth, offsetHeight);

  // 清空img的事件与元素,避免IE内存泄漏

  img.onload = null;

  div.innerHTML = '';

  div.parentNode.removeChild(div);

  };

  };

  check();

  // 定期执行检测

  intervalId = setInterval(check, 150);

  };

  // 等待图片完全加载完毕

  // 这是一个保险操作,如果上面的监听尺寸方法失败则会启用此

  // 如果很小的图像有可能加载时间小于定时器定义的检测间隔时间,则会停止定时器

  img.onload = function () {

  callback(img.width, img.height);

  img.onload = img.onerror = null;

  clearInterval(intervalId);

  container && img.parentNode.removeChild(img);

  };

  // 图像加载错误

  img.onerror = function () {

  error && error();

  clearInterval(intervalId);

  container && img.parentNode.removeChild(img);

  };

  };

  })(jQuery);

  autoIMG压缩后:1.74kb,兼容:Chrome | Firefox | Sifari | Opera | IE6 | IE7 | IE8 | …

  调用演示:$(‘#demo p').autoIMG()

  同样,令人愉悦的DEMO地址在这里:http://demo.glzy8.com/js/2011/autoimg/

  后记:虽然有了上一篇文章imgReady技术的铺垫,我以为会很简单的实现这个图片自适应插件,可是过程中却在webkit内核的浏览器碰了一鼻子灰,后来才得知webkit有BUG未修复,我折腾许久后更新了imgReady函数。

  打包下载地址