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算法中的排序、数组去重详细概述
Oct 14 Javascript
Javascript实现页面跳转的几种方式分享
Oct 26 Javascript
在页面加载完成后通过jquery给多个span赋值
May 21 Javascript
js 获取经纬度的实现方法
Jun 20 Javascript
jQuery DateTimePicker 日期和时间插件示例
Jan 22 Javascript
Vue声明式渲染详解
May 17 Javascript
使用 Node.js 对文本内容分词和关键词抽取
May 27 Javascript
详解jQuery同步Ajax带来的UI线程阻塞问题及解决办法
Aug 09 jQuery
js replace替换字符串同时替换多个方法
Nov 27 Javascript
JavaScript实现的3D旋转魔方动画效果实例代码
Jul 31 Javascript
微信小程序 自定义弹窗实现过程(附代码)
Dec 05 Javascript
vue实现前端列表多条件筛选
Oct 26 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脚本的10个技巧(2)
2006/10/09 PHP
php 函数使用方法与函数定义方法
2010/05/09 PHP
Linux服务器下PHPMailer发送邮件失败的问题解决
2017/03/04 PHP
JavaScript 计算图片加载数量的代码
2011/01/01 Javascript
javascript 常用功能总结
2012/03/18 Javascript
使用Java实现简单的server/client回显功能的方法介绍
2013/05/03 Javascript
javascript中的throttle和debounce浅析
2014/06/06 Javascript
在JavaScript应用中实现延迟加载的方法
2015/06/25 Javascript
JS实现超简洁网页title标题跑动闪烁提示效果代码
2015/10/23 Javascript
Google 地图API资料整理及详细介绍
2016/08/06 Javascript
基于JavaScript实现跳转提示页面
2016/09/24 Javascript
使用Javascript判断浏览器终端设备(PC、IOS(iphone)、Android)
2017/01/04 Javascript
JavaScript遍历查找数组中最大值与最小值的方法示例
2019/05/24 Javascript
小程序使用watch监听数据变化的方法详解
2019/09/20 Javascript
解决vue v-for src 图片路径问题 404
2019/11/12 Javascript
Vue使用预渲染代替SSR的方法
2020/07/02 Javascript
详解微信小程序动画Animation执行过程
2020/09/23 Javascript
python列表操作实例
2015/01/14 Python
Python中的sort()方法使用基础教程
2017/01/08 Python
Python基于QRCode实现生成二维码的方法【下载,安装,调用等】
2017/07/11 Python
浅谈python函数之作用域(python3.5)
2017/10/27 Python
[原创]教女朋友学Python3(二)简单的输入输出及内置函数查看
2017/11/30 Python
对numpy Array [: ,] 的取值方法详解
2018/07/02 Python
关于Keras Dense层整理
2020/05/21 Python
浅谈如何使用python抓取网页中的动态数据实现
2020/08/17 Python
5分钟快速掌握Python定时任务框架的实现
2021/01/26 Python
Dower & Hall官网:英国小众轻奢珠宝品牌
2019/01/31 全球购物
介绍一下Ruby的多线程处理
2013/02/01 面试题
毕业实习个人鉴定范文
2013/12/10 职场文书
小学美术教学反思
2014/02/01 职场文书
小组名称和口号
2014/06/09 职场文书
文秘自荐信
2014/06/28 职场文书
病人家属写给医院的感谢信
2015/01/23 职场文书
毛主席纪念堂观后感
2015/06/17 职场文书
导游词之安徽醉翁亭
2020/01/10 职场文书
用python批量解压带密码的压缩包
2021/05/31 Python