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 相关文章推荐
JS中==与===操作符的比较
Mar 21 Javascript
Ajax搜索结果页面下方的分页按钮的生成
Apr 05 Javascript
AngularJS基础学习笔记之指令
May 10 Javascript
总结在前端排序中遇到的问题
Jul 19 Javascript
jQuery 更改checkbox的状态,无效的解决方法
Jul 22 Javascript
AngularJS实现星星等级评分功能
Sep 24 Javascript
JS比较两个数值的大小实例
Nov 25 Javascript
详解闭包解决jQuery中AJAX的外部变量问题
Feb 22 Javascript
微信小程序动态显示项目倒计时效果
Jun 13 Javascript
微信小程序开发之好友列表字母列表跳转对应位置
Sep 26 Javascript
使用jQuery动态设置单选框的选中效果
Dec 06 jQuery
微信小程序国际化探索实现(附源码地址)
May 20 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的explode和implode的使用说明
2011/07/17 PHP
PHP读取txt文本文件并分页显示的方法
2015/03/11 PHP
详解使用php-cs-fixer格式化代码
2020/09/16 PHP
Jquery命名冲突解决的五种方案分享
2012/03/16 Javascript
JS分页效果示例
2013/10/11 Javascript
jquery实现多行文字图片滚动效果示例代码
2014/10/10 Javascript
JavaScript中number转换成string介绍
2014/12/31 Javascript
js判断手机和pc端选择不同执行事件的方法
2015/01/30 Javascript
JavaScript中setFullYear()方法的使用详解
2015/06/11 Javascript
javascript简单实现类似QQ头像弹出效果的方法
2015/08/03 Javascript
理解JavaScript事件对象
2016/01/25 Javascript
prototype.js常用函数详解
2016/06/18 Javascript
Windows环境下npm install 报错: operation not permitted, rename的解决方法
2016/09/26 Javascript
Vue.js进行查询操作的实例详解
2017/08/25 Javascript
Angular2中监听数据更新的方法
2018/08/31 Javascript
vuejs router history 配置到iis的方法
2018/09/20 Javascript
原生JS实现的自动轮播图功能详解
2018/12/28 Javascript
mpvue微信小程序多列选择器用法之省份城市选择的实现
2019/03/07 Javascript
详解VS Code使用之Vue工程配置format代码格式化
2019/03/20 Javascript
基于three.js实现的3D粒子动效实例代码
2019/04/09 Javascript
javascript数据类型中的一些小知识点(推荐)
2019/04/18 Javascript
微信小程序系列之自定义顶部导航功能
2019/05/21 Javascript
webpack+express实现文件精确缓存的示例代码
2020/06/11 Javascript
vue 虚拟DOM的原理
2020/10/03 Javascript
Python实现的基于优先等级分配糖果问题算法示例
2018/04/25 Python
python 使用 requests 模块发送http请求 的方法
2018/12/09 Python
django框架两个使用模板实例
2019/12/11 Python
Pytorch技巧:DataLoader的collate_fn参数使用详解
2020/01/08 Python
利用python实现凯撒密码加解密功能
2020/03/31 Python
创新型城市实施方案
2014/03/06 职场文书
2014年教师党员公开承诺书
2014/05/28 职场文书
高三励志标语
2014/06/05 职场文书
西安导游词
2015/02/12 职场文书
酒店销售经理岗位职责
2015/04/02 职场文书
python中sys模块的介绍与实例
2021/04/17 Python
Java面试题冲刺第十五天--设计模式
2021/08/07 面试题