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 批量上传图片实现代码
Jan 28 Javascript
关于javascript DOM事件模型的两件事
Jul 22 Javascript
JavaScript作用域链使用介绍
Aug 29 Javascript
jquery.post用法之type设置问题
Feb 24 Javascript
jQuery动态背景图片效果实现方法
Jul 03 Javascript
Vue.js实现无限加载与分页功能开发
Nov 03 Javascript
jQuery图片缩放插件smartZoom使用实例详解
Aug 25 jQuery
Vuex入门到上手教程
Jun 20 Javascript
vue中的ref和$refs的使用
Nov 22 Javascript
微信小程序图片左右摆动效果详解
Jul 13 Javascript
node事件循环和process模块实例分析
Feb 14 Javascript
Vue Router中应用中间件的方法
Aug 06 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实现对xml进行简单的增删改查(CRUD)操作示例
2017/05/19 PHP
基于jQuery的日期选择控件
2009/10/27 Javascript
[原创]js获取数组任意个不重复的随机数组元素
2010/03/15 Javascript
Javascript继承(上)——对象构建介绍
2012/11/08 Javascript
jquery中的事件处理详细介绍
2013/06/24 Javascript
js中opener与parent的区别详细解析
2014/01/14 Javascript
js+css实现tab菜单切换效果的方法
2015/01/20 Javascript
JS实现的简单鼠标跟随DiV层效果完整实例
2015/10/31 Javascript
javascript结合Flexbox简单实现滑动拼图游戏
2016/02/18 Javascript
jquery动态添加文本并获取值的方法
2016/10/12 Javascript
详解微信开发中snsapi_base和snsapi_userinfo及静默授权的实现
2017/03/11 Javascript
EasyUI创建人员树的实例代码
2017/09/15 Javascript
javaScript实现复选框全选反选事件详解
2020/11/20 Javascript
vue2实现数据请求显示loading图
2017/11/28 Javascript
基于vue 动态加载图片src的解决方法
2018/02/05 Javascript
基于Echarts图表在div动态切换时不显示的解决方式
2020/07/20 Javascript
python生成器的使用方法
2013/11/21 Python
Pandas之drop_duplicates:去除重复项方法
2018/04/18 Python
python在文本开头插入一行的实例
2018/05/02 Python
python按键按住不放持续响应的实例代码
2019/07/17 Python
基于Python实现船舶的MMSI的获取(推荐)
2019/10/21 Python
Python二元赋值实用技巧解析
2019/10/25 Python
matplotlib绘制多个子图(subplot)的方法
2019/12/03 Python
keras CNN卷积核可视化,热度图教程
2020/06/22 Python
草莓巧克力:Shari’s Berries
2017/02/07 全球购物
瑞典灯具和照明网上商店:Lamp24.se
2018/03/17 全球购物
L’AGENCE官网:加州女装品牌
2018/06/03 全球购物
教师远程培训感言
2014/03/06 职场文书
请假条的格式
2014/04/11 职场文书
抽样调查项目计划书
2014/04/24 职场文书
普通党员对照检查材料
2014/09/24 职场文书
2014年团支书工作总结
2014/11/14 职场文书
劳模先进事迹材料
2014/12/24 职场文书
给客户的感谢信
2015/01/21 职场文书
2016年优秀共产党员先进事迹材料
2016/02/29 职场文书
浅谈JavaScript作用域
2021/12/06 Javascript