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 相关文章推荐
基于JQuery的浮动DIV显示提示信息并自动隐藏
Feb 11 Javascript
JS(JQuery)操作Array的相关方法介绍
Feb 11 Javascript
浅谈 jQuery 事件源码定位问题
Jun 18 Javascript
对JavaScript的全文搜索实现相关度评分的功能的方法
Jun 24 Javascript
深入理解js generator数据类型
Aug 16 Javascript
JS遍历对象属性的方法示例
Jan 10 Javascript
详解axios 全攻略之基本介绍与使用(GET 与 POST)
Sep 15 Javascript
javascript高仿热血传奇游戏实现代码
Feb 22 Javascript
解决ng-repeat产生的ng-model中取不到值的问题
Oct 02 Javascript
如何基于JS截获动态代码
Dec 25 Javascript
vue 自定义组件的写法与用法详解
Mar 04 Javascript
JS Canvas接口和动画效果大全
Apr 29 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中的日期处理方法集锦
2007/01/02 PHP
php magic_quotes_gpc的一点认识与分析
2008/08/18 PHP
PHP 解决utf-8和gb2312编码转换问题
2010/03/18 PHP
PHP中如何定义和使用常量
2013/02/28 PHP
php计算几分钟前、几小时前、几天前的几个函数、类分享
2014/04/09 PHP
PHP生成等比缩略图类和自定义函数分享
2014/06/25 PHP
php中的curl_multi系列函数使用例子
2014/07/29 PHP
PHP使用finfo_file()函数检测上传图片类型的实现方法
2017/04/18 PHP
PHP实现二维数组中的查找算法小结
2018/06/09 PHP
用javascript实现在小方框中浏览大图的代码
2007/08/14 Javascript
在多个页面使用同一个HTML片段的代码
2011/03/04 Javascript
jQuery使用之标记元素属性用法实例
2015/01/19 Javascript
JavaScript数组迭代器实例分析
2015/06/09 Javascript
JavaScript数据结构与算法之栈与队列
2016/01/29 Javascript
全面了解js中的script标签
2016/07/04 Javascript
javascript常用经典算法详解
2017/01/11 Javascript
JavaScript中双向数据绑定详解
2017/05/03 Javascript
详解如何使用webpack在vue项目中写jsx语法
2017/11/08 Javascript
javascript用rem来做响应式开发
2018/01/13 Javascript
vue配置font-awesome5的方法步骤
2019/01/27 Javascript
灵活使用console让js调试更简单的方法步骤
2019/04/23 Javascript
Vue中用JSON实现刷新界面不影响倒计时
2020/10/26 Javascript
用javascript实现倒计时效果
2021/02/09 Javascript
[01:36:57]【09DOTA2第一视角】小骷髅
2014/04/16 DOTA
python 爬虫如何正确的使用cookie
2020/10/27 Python
CSS3提交意见输入框样式代码
2014/10/30 HTML / CSS
资生堂美国官网:Shiseido美国
2016/09/02 全球购物
June Jacobs尊积帕官网:知名的spa水疗护肤品牌
2019/03/21 全球购物
玩具公司的创业计划书
2013/12/31 职场文书
大学生思想汇报范文
2013/12/31 职场文书
2015年保安个人工作总结
2015/04/02 职场文书
小学生手册家长意见
2015/06/03 职场文书
先进基层党组织事迹材料2016
2016/02/29 职场文书
广告文案的撰写技巧(实用干货)
2019/08/23 职场文书
如何使用vue3打造一个物料库
2021/05/08 Vue.js
JavaScript前端面试组合函数
2022/06/21 Javascript