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控制display属性为none或block
Mar 31 Javascript
JavaScript中对循环语句的优化技巧深入探讨
Jun 06 Javascript
jQuery中noConflict()用法实例分析
Feb 08 Javascript
实现前后端数据交互方法汇总
Apr 07 Javascript
AngularJS模块学习之Anchor Scroll
Jan 19 Javascript
详解JavaScript中双等号引起的隐性类型转换
May 30 Javascript
jQuery模拟完美实现经典FLASH导航动画效果【附demo源码下载】
Nov 09 Javascript
快速搭建React的环境步骤详解
Nov 06 Javascript
React 实现拖拽功能的示例代码
Jan 06 Javascript
一篇文章弄懂javascript中的执行栈与执行上下文
Aug 09 Javascript
Vue.js中使用Vuex实现组件数据共享案例
Jul 31 Javascript
vue-router懒加载的3种方式汇总
Feb 28 Vue.js
再谈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模板引擎SMARTY
2006/10/09 PHP
php利用iframe实现无刷新文件上传功能的代码
2011/09/29 PHP
php实现的简单多进程服务器类完整示例
2020/02/01 PHP
获取当前网页document.url location.href区别总结
2008/05/10 Javascript
jquery 实现上下滚动效果示例代码
2013/08/09 Javascript
angularJS提交表单(form)
2015/02/09 Javascript
浅谈vue.js中v-for循环渲染
2017/07/26 Javascript
javascript浏览器用户代理检测脚本实现方法
2017/10/27 Javascript
Nginx 配置多站点vhost 的方法
2018/01/07 Javascript
webpack vue项目开发环境局域网访问方法
2018/03/20 Javascript
vue.js单文件组件中非父子组件的传值实例
2018/09/13 Javascript
对angular4子路由&辅助路由详解
2018/10/09 Javascript
angularjs实现table表格td单元格单击变输入框/可编辑状态示例
2019/02/21 Javascript
webpack 处理CSS资源的实现
2019/09/27 Javascript
js原生map实现的方法总结
2020/01/19 Javascript
Nuxt页面级缓存的实现
2020/03/09 Javascript
Js Snowflake(雪花算法)生成随机ID的实现方法
2020/08/26 Javascript
[03:34]2014DOTA2西雅图国际邀请赛 淘汰赛7月15日TOPPLAY
2014/07/15 DOTA
[34:47]完美世界DOTA2联赛PWL S2 Magma vs LBZS 第一场 11.18
2020/11/18 DOTA
java直接调用python脚本的例子
2014/02/16 Python
答题辅助python代码实现
2018/01/16 Python
Python中pow()和math.pow()函数用法示例
2018/02/11 Python
Python中实现变量赋值传递时的引用和拷贝方法
2018/04/29 Python
对Python生成器、装饰器、递归的使用详解
2019/07/19 Python
python判断是空的实例分享
2020/07/06 Python
高考考python编程是真的吗
2020/07/20 Python
施华洛世奇英国官网:SWAROVSKI英国
2017/03/13 全球购物
理肤泉俄罗斯官网:La Roche-Posay俄罗斯
2018/07/24 全球购物
巴西购物网站:Onofre Agora
2020/06/08 全球购物
swtich是否能作用在byte上,是否能作用在long上,是否能作用在String上?
2013/03/30 面试题
《每逢佳节倍思亲》教后反思
2014/04/19 职场文书
投资意向书
2014/07/30 职场文书
Python中threading库实现线程锁与释放锁
2021/05/17 Python
python基础之类方法和静态方法
2021/10/24 Python
漫画《尖帽子的魔法工坊》宣布动画化
2022/04/06 日漫
React自定义hook的方法
2022/06/25 Javascript