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 相关文章推荐
javascript中attribute和property的区别详解
Jun 05 Javascript
jQuery窗口、文档、网页各种高度的精确理解
Jul 02 Javascript
Jquery中request和request.form和request.querystring的区别
Nov 26 Javascript
Angular发布1.5正式版,专注于向Angular 2的过渡
Feb 18 Javascript
jquery实现网站列表切换效果的2种方法
Aug 12 Javascript
AngularJS实现按钮提示与点击变色效果
Sep 07 Javascript
基于Vue.js实现简单搜索框
Mar 26 Javascript
微信小程序实现缓存根据不同的id来进行设置和读取缓存
Jun 12 Javascript
用JS实现根据当前时间随机生成流水号或者订单号
May 31 Javascript
windows下create-react-app 升级至3.3.1版本踩坑记
Feb 17 Javascript
Node登录权限验证token验证实现的方法示例
May 25 Javascript
vue自定义右键菜单之全局实现
Apr 09 Vue.js
再谈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
PHP4 与 MySQL 数据库操作函数详解
2006/12/06 PHP
使用PHP遍历文件目录与清除目录中文件的实现详解
2013/06/24 PHP
如何在Mozilla Gecko 用Javascript加载XSL
2007/01/09 Javascript
javascript检查日期格式的函数[比较全]
2008/10/17 Javascript
40款非常棒的jQuery 插件和制作教程(系列一)
2011/10/26 Javascript
form表单只提交数据而不进行页面跳转的解决方案
2013/09/18 Javascript
javascript给span标签赋值的方法
2015/11/26 Javascript
Angularjs 滚动加载更多数据
2016/03/17 Javascript
JavaScript学习小结之使用canvas画“哆啦A梦”时钟
2016/07/24 Javascript
vue.js实现请求数据的方法示例
2017/02/07 Javascript
vue组件与复用详解
2018/04/08 Javascript
JS获取当前时间的年月日时分秒及时间的格式化的方法
2019/12/18 Javascript
js实现自定义右键菜单
2020/05/18 Javascript
[12:29]《一刀刀一天》之DOTA全时刻19:蝙蝠骑士田伯光再度不举
2014/06/10 DOTA
python获取糗百图片代码实例
2013/12/18 Python
给Python初学者的一些编程技巧
2015/04/03 Python
Python循环语句中else的用法总结
2016/09/11 Python
Python实现字典按照value进行排序的方法分析
2017/12/23 Python
Python字符串、整数、和浮点型数相互转换实例
2018/08/04 Python
Linux系统(CentOS)下python2.7.10安装
2018/09/26 Python
Python 实现使用空值进行赋值 None
2020/03/12 Python
基于python实现检索标记敏感词并输出
2020/05/07 Python
python绘制高斯曲线
2021/02/19 Python
Python制作运行进度条的实现效果(代码运行不无聊)
2021/02/24 Python
h5实现获取用户地理定位的实例代码
2017/07/17 HTML / CSS
canvas绘制太极图的实现示例
2020/04/29 HTML / CSS
Rockport乐步美国官网:风靡美国的白宫鞋
2016/11/24 全球购物
演讲稿怎么写
2014/01/07 职场文书
2014年十一国庆向国旗敬礼寄语
2014/04/11 职场文书
2014年党课学习心得体会
2014/07/08 职场文书
大学生简短的自我评价
2014/09/12 职场文书
党员反对四风思想汇报范文
2014/10/25 职场文书
孔繁森观后感
2015/06/10 职场文书
《夸父追日》教学反思
2016/02/20 职场文书
导游词之崇武古城
2019/10/07 职场文书
CentOS7设置ssh服务以及端口修改方式
2022/12/24 Servers