终极完美版javascript获取并限制调整图片尺寸
原文:http://www.qiqiboy.com/2011/01/30/javascript-and-limit-access-to-adjust-the-picture-size.html
好久没更新了,再过几十个小时就农历新年了,这篇是今年最后一篇了,提前预祝大家兔年吉祥如意哈。。。。。
之前我写过一篇《【JavaScript温故知新】获取远程图片的尺寸大小》,文中我提供了获取远程图片尺寸(即图片宽度和高度)的方法。在文末我还附加一段代码,是用来调整图片尺寸的。那段代码并没有什么错误,只是由于我没仔细测试,所以当我现在在我的新主题上应用图片调整功能时,发现了这段代码的的不足之处:主要表现在IE浏览器下,因为IE下图片不能调用onload方法判断加载完毕(状态判断要用onreadystatechange),而浏览器又存在缓存,所以当我动态创建一个图片对象,并载入指定src时,在IE下缓存图片就会被直接载入,但是问题是载入缓存图片时貌似并没有readyState的变化。所以这段代码对于缓存的图片就失效了
img.onreadystatechange=function(){//无效
if(img&&img.readyState&&img.readyState!='complete'){
return false;
}
//....
}
而在非IE浏览器下,即使是缓存的图片载入也有onload触发。
一开始我并没有意识到这点,所以当其他浏览器下都正常时,唯独IE下时而正常,时而无效(正常时其实是因为强刷浏览器,清了缓存,当时我并不知 道)。由于获取图片尺寸的代码中最后有删除插入的测试图片的,但是当我使用IE的开发者工具查看页面DOM时,发现插入在后面的图片节点并没有删除,经过 测试,发现onreadystatechange中的代码完全没有执行。但我实在找不出问题所在,网上搜索也毫无结果。最后我不得不对IE说“I 服了 U”。
解决了IE下的问题,限制图片的尺寸的代码就简单多了,先是获取图片尺寸,这里参数里多了个maxWidth,主要是为了优化图片获取,因为我们是要限制大图片,所以对于页面上已经具有width属性的图片,
/** 获取图片尺寸 by liuqiqi 2011/01//30
* cfg <object> {img:new Image,oncomplete:new Function, maxWidth:Number}
*/
var getImageSize=function(cfg){
/* 如果图片在缓存中或者图片已经指定了宽和高并且小于最大宽度 */
if( cfg.img.complete ||
cfg.img.width &&
cfg.img.height &&
cfg.img.width<cfg.maxWidth ){
cfg.oncomplete.call({
"img":cfg.img,
"width":cfg.img.width,
"height":cfg.img.height
},null);
return;
}
var img=document.createElement('img'),
callback=cfg.oncomplete;
img.src = cfg.img.src;
/* setStytle为我封装的设置样式方法,你如果使用本代码请注意此处,可以使用img.style.position='absolute'..... */
setStyle(img,{
'position':'absolute',
'visibility':'hidden',
'left':'-9999px',
'top':'-9999px'
});
document.body.appendChild(img);
img.onload=img.onerror=img.onreadystatechange=function(){
if(img&&img.readyState&&img.readyState!='loaded'&&img.readyState!='complete'){
return false;
}
img.onload = img.onreadystatechange = img.onerror = null;
callback.call({"img":cfg.img,"width":img.width,"height":img.height},null);
removeNode(img);
img=null;
};
}
上面是获取图片尺寸,接下来就是遍历图片,处理了:
/* id为需要处理的图片所在的容器节点的id,maxWidth即为需要限制的最大宽度 */
function resize_image(id, maxWidth){
if(!$(id))return;
var imgs=$(id).getElementsByTagName('img');
for(var i=0;i<imgs.length;i++){
getImageSize({
"img":imgs[i],
"maxWidth":maxWidth,
"oncomplete":function(){
if(this.width>maxWidth){
var s=this.height/this.width,
width=maxWidth,
height=Math.round(maxWidth*s),
//console.log(this.width+'|'+this.height)
this.img.width=width;
this.img.height=height;
}
}
})
}
}
具体的效果可以在我博客查看。我处理的是宽度超过630的图片,超过630就将最大宽度设置为630,高度相应的按比例缩小。同时给大尺寸图片加上lightbox效果。这个lightbox是我自己写的,效果很简单,但是完全够用。
问题:既然css可以使用max-width限制图片最大宽度,为什么还要使用javascript来处理呢?
答:对于没有自带width和height的图片,使用max-width还以很好的限制宽度,并按比例缩放(IE6除外)。但是,如果图片带了width和height就是另一回事了。
/* 下面的这张图片可以很好的限制最大宽度,并按比例缩放 */
<img src="very-big.png" style="max-width:300px;" />
/* 下面的这张图片宽度可以缩小到300,但是高度依然是600,会导致严重变形*/
<img src="very-big.png" width="900" height="600" style="max-width:300px;" />