2009-08-07

兼容IE6,IE7,IE8和Firefox的图片上传预览效果

类归于: JavaScript — 标签:, , maker @ 00:29

所谓图片上传预览,就是在使用文件选择框选择了文件之后就可以在页面上看见图片的效果,关于这个效果我一直认为是无法做到的,没想到前不久被zhuozi搞定了。

网上流传的一些关于图片上传预览的代码都是差不多的,IE6下使用文件选择对象的value属性取出将要上传的本地文件路径,然后使用本地路径构造img标签,代码如下:

<input type="file"
onchange="document.getElementById('view').innerHTML=' <img src=\'' + this.value + '\'/>';" />
<div id="view"> </div>

网上有些人说上面的代码可以在IE7下生效,但实际测试是不行的,因为IE7的img标签不支持本地路径,所以需要使用div和css的filter来实现这个效果,代码如下:

<input type="file" onchange=‘javascript:
document.getElementById("pic").filters.item("DXImageTransform.Microsoft.AlphaImageLoader").src
= this.value;’ /><br />
<div id="pic"
style="filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=scale);
width:400px;height:200px;"></div>

而关于Firefox的图片上传预览效果,网上几乎找不到相关资料,比较容易想到的解决方案无非是自动将图片上传到服务器再显示出来诸如此类,但这里我们不对此类技术进行讨论,我们要做的是正宗的上传前本地预览。

以下是最后的研究结果,同时兼容IE6,IE7,IE8和Firefox

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script>
var picPath;
var image;
// preview picture
function preview()
{
document.getElementById('preview').style.display = 'none';
// 下面代码用来获得图片尺寸,这样才能在IE下正常显示图片
document.getElementById('box').innerHTML
= "<img width='"+image.width+"' height='"+image.height+"' id='aPic' src='"+picPath+"'>";
}
// show view button
function buttonShow()
{
/*
这里用来解决图片加载延时造成的预览失败.
简单说明一下,当image对象的src属性发生改变时JavaScript会重新给image装载图片内容,
这通常是需要一些时间的,如果在加载完成之前想将图片显示出来就会造成错误,所以我们
通过图片的宽度和高度来判断图片是否已经被成功加载,加载完毕才会显示预览按钮.
这里我仍然有一个困惑,在IE7下预览效果偶尔会失效.
*/
if ( image.width == 0 || image.height == 0 ) {
setTimeout(buttonShow, 1000);
} else {
document.getElementById('preview').style.display = 'block';
}
}
function loadImage(ele) {
picPath   = getPath(ele);
image     = new Image();
image.src = picPath;
setTimeout(buttonShow, 1000);
}
function getPath(obj)
{
if(obj)
{
//ie
if (window.navigator.userAgent.indexOf("MSIE")>=1)
{
obj.select();
// IE下取得图片的本地路径
return document.selection.createRange().text;
}
//firefox
else if(window.navigator.userAgent.indexOf("Firefox")>=1)
{
if(obj.files)
{
// Firefox下取得的是图片的数据
return obj.files.item(0).getAsDataURL();
}
return obj.value;
}
return obj.value;
}
}
</script>
</head>
<body>
<input type="file" name="pic" id="pic" onchange='loadImage(this)' />
<input id='preview' type='button' value='preview' style='display:none;' onclick='preview();'>
<div id='box'></div>
</body>
</html>

补充:
上面的代码经过测试貌似不是那么稳定,一些机器上的IE7会失效,我在6台电脑上测试,FF全通过,IE7下有一台没有通过,估计是和IE的设置有关, 而且即使可以正常使用也不是每次都可以成功显示出预览按钮,这个原因也没有找到,估计是图片加载失败什么的,所以例子里特殊处理的预览按钮的显示,即时预览功能失败也不影响其他功能。

下面是在我机器上IE7的测试图片:

image-upload-preview-ie7

10 条评论 »

  1. 找了一下午,搞了个IE可用但FF不兼容的版本。
    学习受用了!

    Comment 由 minghao — 2009-08-07 @ 18:20

  2. IE7不行呀~
    这个只能IE6和FF饿。。。

    Comment 由 callous — 2009-08-13 @ 10:46

  3. 关于IE7的问题也令我很头痛,我在6台机器的IE7上做测试,5台通过,1台未通过,原因不明。 估计是和安全设置有关, 不过目前也没有更好的办法,要不就将这个代码再改改,用上面介绍的IE7的方法来处理。

    Comment 由 maker — 2009-08-13 @ 10:53

  4. 谢谢!收藏了!

    Comment 由 cary — 2009-10-22 @ 10:32

  5. 这个设置

    http://images.cnblogs.com/cnblogs_com/shunyao8210/01.jpg

    Comment 由 net_lover — 2009-11-20 @ 16:53

  6. 网页在本地,图片可以预览,如果这个页面在服务器看看能预览不

    Comment 由 小强.假的 — 2009-12-31 @ 13:02

  7. 这里也有一个图片上传预览
    http://www.cnblogs.com/cloudgamer/archive/2009/12/22/ImagePreview.html
    用的差不多的方法

    Comment 由 cc — 2010-03-08 @ 08:32

  8. 为什么有些图片IE预览不了,火狐却可以啊?
    待解决

    Comment 由 jak — 2010-07-28 @ 14:35

  9. IE7要添加信任站点

    Comment 由 yoyo — 2010-10-22 @ 08:54

  10. 这个算是不错的了.比其它网上的垃圾好多了.谢谢分享.

    Comment 由 你好 — 2011-06-10 @ 09:44

这篇文章上的评论 RSS feed TrackBack URL

留下评论

WordPress 所驱动