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有关的小细节
Apr 02 Javascript
JavaScript格式化数字的函数代码
Nov 30 Javascript
JQueryEasyUI datagrid框架的基本使用
Apr 08 Javascript
jQuery教程 $()包装函数来实现数组元素分页效果
Aug 13 Javascript
js实现全屏漂浮广告移入光标停止移动
Dec 02 Javascript
二叉树的非递归后序遍历算法实例详解
Feb 07 Javascript
js实现键盘上下左右键选择文字并显示在文本框的方法
May 07 Javascript
js字符串截取函数slice、substring和substr的比较
May 17 Javascript
Bootstrap简单表单显示学习笔记
Nov 15 Javascript
基于JQuery的Ajax方法使用详解
Aug 16 jQuery
AngularJS实现的锚点楼层跳转功能示例
Jan 02 Javascript
Vue 中使用 typescript的方法详解
Feb 17 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获取远程文件大小
2015/10/20 PHP
Zend Framework框架实现类似Google搜索分页效果
2016/11/25 PHP
Laravel中Facade的加载过程与原理详解
2017/09/22 PHP
PHP数组array类常见操作示例
2020/05/15 PHP
JavaScript中获取未知对象属性的代码
2011/04/27 Javascript
最短的javascript:地址栏载入脚本代码
2011/10/13 Javascript
关于图片按比例自适应缩放的js代码
2011/10/30 Javascript
jQuery 绑定事件到动态创建的元素上的方法实例
2013/08/18 Javascript
文本域光标操作的jQuery扩展分享
2014/03/10 Javascript
jQuery中hover与mouseover和mouseout的区别分析
2015/12/24 Javascript
深入理解Javascript中的观察者模式
2017/02/20 Javascript
Vue监听数组变化源码解析
2017/03/09 Javascript
React中常见的动画实现的几种方式
2018/01/10 Javascript
最后说说Vue2 SSR 的 Cookies 问题
2018/05/25 Javascript
详解@Vue/Cli 3 Invalid Host header 错误解决办法
2019/01/02 Javascript
JavaScript适配器模式原理与用法实例详解
2020/03/09 Javascript
Vue实现PC端靠边悬浮球的代码
2020/05/09 Javascript
Vue使用富文本编辑器Vue-Quill-Editor(含图片自定义上传服务、清除复制粘贴样式等)
2020/05/15 Javascript
零基础写python爬虫之使用Scrapy框架编写爬虫
2014/11/07 Python
在Python的Django框架上部署ORM库的教程
2015/04/20 Python
Python语言实现机器学习的K-近邻算法
2015/06/11 Python
python django 访问静态文件出现404或500错误
2017/01/20 Python
Scrapy抓取京东商品、豆瓣电影及代码分享
2017/11/23 Python
python中的字典操作及字典函数
2018/01/03 Python
Android基于TCP和URL协议的网络编程示例【附demo源码下载】
2018/01/23 Python
influx+grafana自定义python采集数据和一些坑的总结
2018/09/17 Python
对python自动生成接口测试的示例讲解
2018/11/30 Python
浅析Python 引号、注释、字符串
2019/07/25 Python
Python如何实现爬取B站视频
2020/05/20 Python
基于Python制作一副扑克牌过程详解
2020/10/19 Python
Mountain Hardwear官网:攀岩服装和户外装备
2019/09/26 全球购物
机械设备与数控技术专业求职信
2014/08/10 职场文书
企业法人授权委托书范本
2014/09/23 职场文书
2016年“5.12”护士节致辞
2015/07/31 职场文书
2019年第四季度财务部门工作计划
2019/11/02 职场文书
解决Go gorm踩过的坑
2021/04/30 Golang