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


Posted in Javascript onMarch 12, 2011

为了防止图片撑破布局,最常见的仍然是通过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.3water.com/js/2011/autoimg/
后记:虽然有了上一篇文章imgReady技术的铺垫,我以为会很简单的实现这个图片自适应插件,可是过程中却在webkit内核的浏览器碰了一鼻子灰,后来才得知webkit有BUG未修复,我折腾许久后更新了imgReady函数。
打包下载地址
Javascript 相关文章推荐
ASP.NET中使用后端代码注册脚本 生成JQUERY-EASYUI的界面错位的解决方法
Jun 12 Javascript
包含中国城市的javascript对象实例
Aug 03 Javascript
jQuery获取checkbox选中的值
Jan 28 Javascript
浅谈使用splice函数对数组中的元素进行删除时的注意事项
Dec 04 Javascript
JS简单获取当前日期和农历日期的方法
Apr 17 Javascript
Vue2.0 组件传值通讯的示例代码
Aug 01 Javascript
微信小程序methods中定义的方法互相调用的实例代码
Aug 07 Javascript
浅谈vue后台管理系统权限控制思考与实践
Dec 19 Javascript
小试SVG之新手小白入门教程
Jan 08 Javascript
vue操作动画的记录animate.css实例代码
Apr 26 Javascript
初学vue出现空格警告的原因及其解决方案
Oct 31 Javascript
javascript数组includes、reduce的基本使用
Jul 02 Javascript
再谈javascript图片预加载技术(详细演示)
Mar 12 #Javascript
在jQuery1.5中使用deferred对象 着放大镜看Promise
Mar 12 #Javascript
使用jquery插件实现图片延迟加载技术详细说明
Mar 12 #Javascript
Jquery.LazyLoad.js修正版下载,实现图片延迟加载插件
Mar 12 #Javascript
javascript textarea光标定位方法(兼容IE和FF)
Mar 12 #Javascript
JavaScript全局函数使用简单说明
Mar 11 #Javascript
js+css使DIV始终居于屏幕中间 左下 左上 右上 右下的代码集合
Mar 10 #Javascript
You might like
ip签名探针
2006/10/09 PHP
smarty基础之拼接字符串的详解
2013/06/18 PHP
PHP中加密解密函数与DES加密解密实例
2014/10/17 PHP
Laravel5.1数据库连接、创建数据库、创建model及创建控制器的方法
2016/03/29 PHP
PHP的mysqli_thread_id()函数讲解
2019/01/24 PHP
javascript 处理HTML元素必须避免使用的一种方法
2009/07/30 Javascript
js 判断计算字符串长度/判断空的简单方法
2013/08/05 Javascript
用js读、写、删除Cookie代码分享及详细注释说明
2014/06/05 Javascript
jQuery中extend函数的实现原理详解
2015/02/03 Javascript
JS响应鼠标点击实现两个滑块区间拖动效果
2015/10/26 Javascript
体验jQuery和AngularJS的不同点及AngularJS的迷人之处
2016/02/02 Javascript
原生js和jquery分别实现横向导航菜单效果
2016/05/13 Javascript
Google 地图叠加层实例讲解
2016/08/06 Javascript
JS基于for语句编写的九九乘法表示例
2018/01/04 Javascript
Vue中使用 setTimeout() setInterval()函数的问题
2018/09/13 Javascript
微信小程序利用swiper+css实现购物车商品删除功能
2019/03/06 Javascript
jquery+php后台实现省市区联动功能示例
2019/05/23 jQuery
微信小程序 扭蛋抽奖机css3动画实现详解
2019/07/19 Javascript
DWR内存兼容及无法调用问题解决方案
2020/10/16 Javascript
Python利用多进程将大量数据放入有限内存的教程
2015/04/01 Python
Python画图学习入门教程
2016/07/01 Python
Python面向对象程序设计之私有属性及私有方法示例
2019/04/08 Python
Python中py文件转换成exe可执行文件的方法
2019/06/14 Python
Python利用WMI实现ping命令的例子
2019/08/14 Python
关于Python3 lambda函数的深入浅出
2019/11/27 Python
细说CSS3中box属性中的overflow-x属性和overflow-y属性值的效果
2014/07/21 HTML / CSS
基于HTML5代码实现折叠菜单附源码下载
2015/11/27 HTML / CSS
Timberland澳大利亚官网:全球领先的户外品牌
2019/12/10 全球购物
加拿大领先家居家具网上购物:Aosom.ca
2020/05/27 全球购物
介绍一下Linux文件的记录形式
2013/09/29 面试题
Python如何定义一个函数
2015/09/01 面试题
网络工程师的自我评价
2013/10/02 职场文书
学前教育专业毕业生自荐信
2013/10/03 职场文书
保密工作整改情况汇报
2014/11/06 职场文书
三国演义读书笔记
2015/06/25 职场文书
四年级数学教学反思
2016/02/16 职场文书