还在继续奋斗那个HTML编辑器。发现碰到很多问题,觉得WEB开发原来也是那么有深度,并不像在学校的时候觉得的那样比桌面开发要低级。
今天要要做的就是插入图片的功能。既然是在HTML编辑器中用,那么上传图片当然是要无刷新的。首先我就想到了AJAX,但是AJAX没有办法实现表单上传啊,虽然网上也有AJAX实现上传的例子,但是感觉不太实际而且不通用,只好采取第二种方案,用IFrame实现。
最开始的做法是服务端在接受完文件之后,将文件的路径放在一个数组中,然后用response写一段调用父帧的js语句:
//服务端response写的js语句
var filenames = ["upload/upload_1.jpg","upload/upload_2.jpg"];
parent.callback(filenames);
//父帧的callback方法
function callback(filename){
//用循环呈现filenames,可以用DOM也可以用innerHTML,略
}
好了,就这么简单,无刷上传并显示就这么完成了,但是如果要上传的是1024*768或者更大的1600*1200的图片,显示出来那整个页面就都是图片了。这作为一个HTML编辑器显然是不可行的,那就需要缩略显示了。
上网搜了一下,用js实现缩略图,看大部分都是用这样的方法实现的,感觉还不错,保持了长宽比。
function scale(o){
var maxW = 200;//限制的最高长宽
var maxH = 200;
var width = o.offsetWidth;
var height = o.offsetHeight;
var wdh = width/height;
var hdw = height/width;
//本来这里还要加个if(o.complete)来判断图片是不是已经加载完,但是在我的IE里每次都是false,所以就没加,但是好像对结果没什么影响,待检测!
if(width>maxW){
width = maxW;
height = width*hdw;
}
if(height>maxH){
height = maxH;
width = height*wdh;
}
o.width = width;
o.height = height;
}
但是在什么时候对图片进行缩放呢,这个我可是大费脑筋了。最后还是选择用onload来进行缩放。
{
....
var img = new Image();
img.src = filenames[i];
img.onload = new function(){
scale(img);
};
....
}
结果发现在ff里什么都显示不出来,在ie显示出来了但是没有缩略,后来网上找了一下,说是缓存问题,要把onload放在src前面,照做了发现问题照旧。后来试了一下用innerHTML发现可以了,小小开心了一把。但是还是不完美,每次都要闪一下才会出现缩略图,因为首先显示大图然后再变小的。于是尝试先把图片显示出来,缩小之后再显示,但是用了display="none"发现在试图获取img的长宽是都为0(这是正常的)。又用了visibility="hidden",发现也没用,因为visibility="hidden",其实img还是占据着它的位置。
实在是没辙了,脑袋中灵光一闪,可以现在IFrame里显示图片得到长宽之后再在父帧中显示缩略图。
于是用response直接写html代码:
<img src='upload/upload_37607.jpg' onload='parent.scale(this);'>
<img src='upload/upload_37608.jpg' onload='parent.scale(this);'>
<img src='upload/upload_37609.JPG' onload='parent.scale(this);'>
<img src='upload/upload_37610.jpg' onload='parent.scale(this);'>
<img src='upload/upload_37611.jpg' onload='parent.scale(this);'>
然后在scale中往父帧中放图片,终于“完美”实现,不过还是很粗糙啊,以后有空再想想有没有更好的办法吧。
PS:有个要注意的地方是隐藏的IFrame不能用"display:none;"而要用"visibility="hidden";width=1;height=1;",不然得到的img的长宽还是0,width和height为0的话,得到的img的长宽也是0。