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 完美图片新闻轮转效果,腾讯大粤网首页图片轮转改造而来
Nov 21 Javascript
node.js学习总结之调式代码的方法
Jun 25 Javascript
express的中间件basicAuth详解
Dec 04 Javascript
JavaScript中使用Callback控制流程介绍
Mar 16 Javascript
JavaScript运算符小结
Jun 03 Javascript
实例讲解避免javascript冲突的方法
Jan 03 Javascript
JS中判断字符串中出现次数最多的字符及出现的次数的简单实例
Jun 03 Javascript
angular4中*ngFor不能对返回来的对象进行循环的解决方法
Sep 12 Javascript
javascript获取元素的计算样式
May 24 Javascript
vue实现滑动超出指定距离回顶部功能
Jul 31 Javascript
原生javascript的ajax请求及后台PHP响应操作示例
Feb 24 Javascript
JavaScript交换变量的常用方法小结【4种方法】
May 07 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
我的论坛源代码(一)
2006/10/09 PHP
php文件上传表单摘自drupal的代码
2011/02/15 PHP
PHP中strcmp()和strcasecmp()函数字符串比较用法分析
2016/01/07 PHP
thinkphp3.2.3版本的数据库增删改查实现代码
2016/09/22 PHP
PHP使用Curl实现模拟登录及抓取数据功能示例
2018/04/27 PHP
laravel 框架执行流程与原理简单分析
2020/02/01 PHP
如何通过PHP实现Des加密算法代码实例
2020/05/09 PHP
Firefox+FireBug使JQuery的学习更加轻松愉快
2010/01/01 Javascript
js与jquery中获取当前鼠标的x、y坐标位置的代码
2011/05/23 Javascript
Javascript 页面模板化很多人没有使用过的方法
2012/06/05 Javascript
javascript中数组中求最大值示例代码
2013/12/18 Javascript
JS操作CSS随机改变网页背景实现思路
2014/03/10 Javascript
javascript从image转换为base64位编码的String
2014/07/29 Javascript
js设置document.domain实现跨域的注意点分析
2015/05/21 Javascript
将form表单通过ajax实现无刷新提交的简单实例
2016/10/12 Javascript
Javascript 数组去重的方法(四种)详解及实例代码
2016/11/24 Javascript
js实现图片轮播效果学习笔记
2017/07/26 Javascript
vue项目使用.env文件配置全局环境变量的方法
2019/10/24 Javascript
Vue3 的响应式和以前有什么区别,Proxy 无敌?
2020/05/20 Javascript
jQuery实现简单日历效果
2020/07/05 jQuery
[05:31]DOTA2英雄梦之声_第04期_光之守卫
2014/06/23 DOTA
windows下python安装paramiko模块和pycrypto模块(简单三步)
2017/07/06 Python
python实现多线程行情抓取工具的方法
2018/02/28 Python
Python实现的自定义多线程多进程类示例
2018/03/23 Python
详解python项目实战:模拟登陆CSDN
2019/04/04 Python
通过python实现弹窗广告拦截过程详解
2019/07/10 Python
python通过TimedRotatingFileHandler按时间切割日志
2019/07/17 Python
优衣库台湾官网:UNIQLO台湾
2019/02/01 全球购物
英国女性化妆品收纳和家具网站:Beautify
2019/12/07 全球购物
工作态度检讨书
2014/02/11 职场文书
教师职称自我鉴定
2014/02/12 职场文书
财务部副经理岗位职责
2014/03/14 职场文书
司法所长先进事迹
2014/06/02 职场文书
商场父亲节活动方案
2014/08/27 职场文书
Redis分布式锁的7种实现
2022/04/01 Redis
Python可视化神器pyecharts绘制水球图
2022/07/07 Python