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 相关文章推荐
iframe的onload在Chrome/Opera中执行两次Bug的解决方法
Mar 17 Javascript
用jquery方法操作radio使其默认选项是否
Sep 10 Javascript
Node.js中使用事件发射器模式实现事件绑定详解
Aug 15 Javascript
JavaScript通过this变量快速找出用户选中radio按钮的方法
Mar 23 Javascript
jQuery+css实现的蓝色水平二级导航菜单效果代码
Sep 11 Javascript
jQuery代码实现表格中点击相应行变色功能
May 09 Javascript
浅谈几种常用的JS类定义方法
Jun 08 Javascript
vue动态组件实现选项卡切换效果
Mar 08 Javascript
jquery+css实现简单的图片轮播效果
Aug 07 jQuery
JavaScript如何获取到导航条中HTTP信息
Oct 10 Javascript
vue3.0 CLI - 2.3 - 组件 home.vue 中学习指令和绑定
Sep 14 Javascript
JavaScript小技巧带你提升你的代码技能
Sep 15 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
在PHP中使用反射技术的架构插件使用说明
2010/05/18 PHP
免费的ip数据库淘宝IP地址库简介和PHP调用实例
2014/04/08 PHP
Yii中CGridView关联表搜索排序方法实例详解
2014/12/03 PHP
PHP实现批量上传单个文件
2015/12/29 PHP
Yii2实现上下联动下拉框功能的方法
2016/08/10 PHP
PHP实现防盗链的方法分析
2017/07/25 PHP
PHP实现一个多功能购物网站的案例
2017/09/13 PHP
PHP自定义函数实现assign()数组分配到模板及extract()变量分配到模板功能示例
2018/05/23 PHP
MacOS下PHP7.1升级到PHP7.4.15的方法
2021/02/22 PHP
使用jquery为table动态添加行的实现代码
2011/03/30 Javascript
Jquery 选中表格一列并对表格排序实现原理
2012/12/15 Javascript
jquery实现漂浮在网页右侧的qq在线客服插件示例
2013/05/13 Javascript
JS获得URL超链接的参数值实例代码
2013/06/21 Javascript
javascript中比较字符串是否相等的方法
2013/07/23 Javascript
jquery.cookie用法详细解析
2013/12/18 Javascript
详解JavaScript中的事件流和事件处理程序
2016/05/20 Javascript
AngularJS上拉加载问题解决方法
2016/05/23 Javascript
javascript类型系统——undefined和null全面了解
2016/07/13 Javascript
探索Javascript中this的奥秘
2016/12/11 Javascript
JS基于面向对象实现的多个倒计时器功能示例
2017/02/28 Javascript
详解Vue快速零配置的打包工具——parcel
2018/01/16 Javascript
Vue 中获取当前时间并实时刷新的实现代码
2020/05/12 Javascript
基于openlayers实现角度测量功能
2020/09/28 Javascript
element中Steps步骤条和Tabs标签页关联的解决
2020/12/08 Javascript
[01:18]DOTA2超级联赛专访hanci ForLove淘汰感言曝光
2013/06/04 DOTA
pygame学习笔记(3):运动速率、时间、事件、文字
2015/04/15 Python
深入浅析Python中join 和 split详解(推荐)
2016/06/30 Python
Python实现将数据框数据写入mongodb及mysql数据库的方法
2018/04/02 Python
对python中Librosa的mfcc步骤详解
2019/01/09 Python
python中pytest收集用例规则与运行指定用例详解
2019/06/27 Python
解决Django加载静态资源失败的问题
2019/07/28 Python
python使用turtle库绘制奥运五环
2020/02/24 Python
pytorch Dataset,DataLoader产生自定义的训练数据案例
2021/03/03 Python
安全的后院和健身蹦床:JumpSport
2019/07/15 全球购物
高中的自我鉴定
2013/12/16 职场文书
车间副主任岗位职责
2013/12/24 职场文书