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 相关文章推荐
javascript showModalDialog模态对话框使用说明
Dec 31 Javascript
漂亮的jquery提示效果(仿腾讯弹出层)
Feb 05 Javascript
javascript将异步校验表单改写为同步表单
Jan 27 Javascript
jQuery实现仿微软首页感应鼠标变化滑动窗口效果
Oct 08 Javascript
深入浅析JavaScript面向对象和原型函数
Feb 06 Javascript
基于 Immutable.js 实现撤销重做功能的实例代码
Mar 01 Javascript
vue中的模态对话框组件实现过程
May 01 Javascript
深入Vue-Router路由嵌套理解
Aug 13 Javascript
webpack css加载和图片加载的方法示例
Sep 11 Javascript
使用JavaScript解析URL的方法示例
Mar 01 Javascript
详解Vue 全局变量,局部变量
Apr 17 Javascript
小程序扫描普通链接二维码跳转小程序指定界面方法
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
动画 《Pokemon Sword·Shield》系列WEB动画《薄明之翼》第2话声优阵容公开!
2020/03/06 日漫
php中关于普通表单多文件上传的处理方法
2011/03/25 PHP
php使用fgetcsv读取csv文件出现乱码的解决方法
2014/11/08 PHP
php中使用key,value,current,next和prev函数遍历数组的方法
2015/03/17 PHP
Yii使用Captcha验证码的方法
2015/12/28 PHP
十分钟打造AutoComplete自动完成效果代码
2009/12/26 Javascript
jQuery ul标签下拉菜单演示代码
2010/12/11 Javascript
自定义一个jquery插件[鼠标悬浮时候 出现说明label]
2011/06/27 Javascript
jquery实现通用版鼠标经过淡入淡出效果
2014/06/15 Javascript
node.js学习总结之调式代码的方法
2014/06/25 Javascript
jsTree使用记录实例
2016/12/01 Javascript
vue mint-ui学习笔记之picker的使用
2017/10/11 Javascript
详解如何在angular2中获取节点
2017/11/23 Javascript
使用Bootstrap + Vue.js实现表格的动态展示、新增和删除功能
2017/11/27 Javascript
vue项目上传Github预览的实现示例
2018/11/06 Javascript
AngularJs中$cookies简单用法分析
2019/05/30 Javascript
细说Vue组件的服务器端渲染的过程
2019/05/30 Javascript
js实现简单页面全屏
2019/09/17 Javascript
Nodejs + sequelize 实现增删改查操作
2020/11/07 NodeJs
原生js实现弹窗消息动画
2020/11/20 Javascript
vue中如何自定义右键菜单详解
2020/12/08 Vue.js
Python中使用Tkinter模块创建GUI程序实例
2015/01/14 Python
ansible作为python模块库使用的方法实例
2017/01/17 Python
pandas中Timestamp类用法详解
2017/12/11 Python
numpy中实现ndarray数组返回符合特定条件的索引方法
2018/04/17 Python
python的set处理二维数组转一维数组的方法示例
2019/05/31 Python
Python flask框架post接口调用示例
2019/07/03 Python
搭建python django虚拟环境完整步骤详解
2019/07/08 Python
200行python代码实现2048游戏
2019/07/17 Python
Python+Selenium+phantomjs实现网页模拟登录和截图功能(windows环境)
2019/12/11 Python
浅谈对pytroch中torch.autograd.backward的思考
2019/12/27 Python
Python生成词云的实现代码
2020/01/14 Python
python实现密度聚类(模板代码+sklearn代码)
2020/04/27 Python
详解scrapy内置中间件的顺序
2020/09/28 Python
学校运动会霸气口号
2014/06/07 职场文书
文员岗位职责范本
2015/04/16 职场文书