- JS兼容各个浏览器的本地图片上传即时预览效果
-
很早以前 在杭州银行工作曾经碰到这么一个需求,当时也是纠结了很久,也是google了很久,没有碰到合适的demo,今天特意研究了下这方面的的问题,所以也就做了个简单的demo来实现 本地上传图片即时预览效果。其在标准
浏览器(firefox,chrome,IE10等其他浏览器)用了HTML5中的内容实现图片即时预览效果。在IE10以下浏览器用了滤镜来解决图片显示问题。在看代码之前,先让我们来了解以下知识点:
HTML5中的FileReader对象: FileReader对象主要是把文件读入内存中,并且读取文件中数据。目前为止,firefox3.6+ chrome6+ Safari5.2+ Opera11+及IE10浏览器支持FileReader对象。它有以下5种方法:1. readBinaryString2. readAsText3. readAsDataURL 将对象或文件中的数据读取为一串DataURL字符串,就是将数据以一种特殊格式的URL地址形式直接读入页面。4. readAsArrayBuffer5. abort.而我们现在要用的是第三种,所以解释了下,其他的具体可以看相关的资料,这里不多解释。IE:document.selection 即资料解释如下:selection 对象 代表了当前激活选中区,即高亮文本块,和/或文档中用户可执行某些操作的其它元素。selection 对象的典型用途是作为用户的输入,以便识别正在对文档的哪一部分正在处理,或者作为某一操作的结果输出给用户。用户和脚本都可以创建选中区。用户创建选中区的办法是拖曳文档的一部分。脚本创建选中区的办法是在文本区域或类似对象上调用 select 方法。要获取当前选中区,请对 document 对象应用 selection 关键字。要对选中区执行操作,请先用 createRange 方法从选中区创建一个文本区域对象。一个文档同一时间只能有一个选中区。选中区的类型决定了其中为空或者包含文本和/或元素块。尽管空的选中区不包含任何内容,你仍然可以用它作为文档中的位置标志。下面是JSFiddle 中的DEMO链接如下:想要查看效果,请点击我!下面是HTML代码如下:复制代码<form enctype="multipart/form-data" name="form1"><input id="f" type="file" name="f" οnchange="change()" /><div class="upload">上传图片</div><p>预览:</p><p><img id="preview" alt="" name="pic" /></p></form>复制代码JS代码如下:复制代码function change() {var pic = document.getElementById("preview"),file = document.getElementById("f");var ext=file.value.substring(file.value.lastIndexOf(".")+1).toLowerCase();// gif在IE浏览器暂时无法显示if(ext!='png'&&ext!='jpg'&&ext!='jpeg'){alert("图片的格式必须为png或者jpg或者jpeg格式!");return;}var isIE = navigator.userAgent.match(/MSIE/)!= null,isIE6 = navigator.userAgent.match(/MSIE 6.0/)!= null;if(isIE) {file.select();var reallocalpath = document.selection.createRange().text;// IE6浏览器设置img的src为本地路径可以直接显示图片if (isIE6) {pic.src = reallocalpath;}else {// 非IE6版本的IE由于安全问题直接设置img的src无法显示本地图片,但是可以通过滤镜来实现pic.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod='image',src=\"" + reallocalpath + "\")";// 设置img的src为base64编码的透明图片 取消显示浏览器默认图片pic.src = 'data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==';}}else {html5Reader(file);}}function html5Reader(file){var file = file.files[0];var reader = new FileReader();reader.readAsDataURL(file);reader.onload = function(e){var pic = document.getElementById("preview");pic.src=this.result;}}
实现要点
● 对于 Chrome、Firefox、IE10 使用 FileReader 来实现。
● 对于 IE6~9 使用滤镜 filter:progid:DXImageTransform.Microsoft.AlphaImageLoader 来实现。
实现代码
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<style type="text/css">
#preview, .img, img
{
width:200px;
height:200px;
}
#preview
{
border:1px solid #000;
}
</style>
</head>
<body>
<div id="preview"></div>
<input type="file" οnchange="preview(this)" />
<script type="text/javascript">
function preview(file)
{
var prevDiv = document.getElementById('preview');
if (file.files && file.files[0])
{
var reader = new FileReader();
reader.onload = function(evt){
prevDiv.innerHTML = '<img src="' + evt.target.result + '" />';
}
reader.readAsDataURL(file.files[0]);
}
else
{
prevDiv.innerHTML = '<div class="img" style="filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=scale,src=\'' + file.value + '\'"></div>';
}
}
</script>
</body>
</html>
http://www.cnblogs.com/slyzly/articles/2411940.html
html代码
<div id="divPreview">
<img id="imgHeadPhoto" src="Images/Headphoto/noperson.jpg" style="width: 160px; height: 170px;border: solid 1px #d2e2e2;" alt="" />
</div>
<asp:FileUpload ID="fuHeadPhoto" runat="server" οnchange="PreviewImage(this,'imgHeadPhoto','divPreview')" size="20" />
将网上的js本地图片预览整合了一下,希望对大家有用,如有其他浏览器不兼容且有解决办法,请给我留言,我将及时更新本文代码。
javascript代码
//js本地图片预览,兼容ie[6-9]、火狐、Chrome17+、Opera11+、Maxthon3、360浏览器 function PreviewImage(fileObj, imgPreviewId, divPreviewId) { var allowExtention = document.getElementById("hfAllowPicSuffix").value; //.jpg,.bmp,.gif,.png,允许上传文件的后缀名 var extention = fileObj.value.substring(fileObj.value.lastIndexOf(".") + 1).toLowerCase(); //获取当前上传文件的扩展名 var browserVersion = window.navigator.userAgent.toUpperCase(); if (allowExtention.indexOf(extention) > -1) { if (fileObj.files) {//兼容chrome、火狐7+、360浏览器5.5+等,应该也兼容ie10,HTML5实现预览 if (window.FileReader) { var reader = new FileReader(); reader.onload = function(e) { document.getElementById(imgPreviewId).setAttribute("src", e.target.result); } reader.readAsDataURL(fileObj.files[0]); } else if (browserVersion.indexOf("SAFARI") > -1) { alert("不支持Safari浏览器6.0以下版本的图片预览!"); } else { alert("不支持您当前使用的浏览器的图片预览!"); } } else if (browserVersion.indexOf("MSIE") > -1) {//ie、360低版本预览 if (browserVersion.indexOf("MSIE 6") > -1) {//ie6 document.getElementById(imgPreviewId).setAttribute("src", fileObj.value); } else {//ie[7-9] fileObj.select(); if (browserVersion.indexOf("MSIE 9") > -1) { //fileObj.blur(); //不加上document.selection.createRange().text在ie9会拒绝访问 document.getElementById(divPreviewId).focus(); //参考http://gallop-liu.iteye.com/blog/1344778 } var newPreview = document.getElementById(divPreviewId + "New"); if (newPreview == null) { newPreview = document.createElement("div"); newPreview.setAttribute("id", divPreviewId + "New"); newPreview.style.width = document.getElementById(imgPreviewId).width + "px"; newPreview.style.height = document.getElementById(imgPreviewId).height + "px"; newPreview.style.border = "solid 1px #d2e2e2"; } newPreview.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod='scale',src='" + document.selection.createRange().text + "')"; var tempDivPreview = document.getElementById(divPreviewId); tempDivPreview.parentNode.insertBefore(newPreview, tempDivPreview); tempDivPreview.style.display = "none"; } } else if (browserVersion.indexOf("FIREFOX") > -1) {//firefox var firefoxVersion = parseFloat(browserVersion.toLowerCase().match(/firefox\/([\d.]+)/)[1]); if (firefoxVersion < 7) {//firefox7以下版本 document.getElementById(imgPreviewId).setAttribute("src", fileObj.files[0].getAsDataURL()); } else {//firefox7.0+ document.getElementById(imgPreviewId).setAttribute("src", window.URL.createObjectURL(fileObj.files[0])); } } else { alert("不支持您当前使用的浏览器的图片预览!"); } } else { alert("仅支持" + allowExtention + "为后缀名的文件!"); fileObj.value = ""; //清空选中文件 if (browserVersion.indexOf("MSIE") > -1) { fileObj.select(); document.selection.clear(); } fileObj.outerHTML = fileObj.outerHTML; } }完整的的测试。html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title></title>
</head>
<body>
<div id="divPreview">
<img id="imgHeadPhoto" src="noperson.jpg" style="width: 160px; height: 170px; border: solid 1px #d2e2e2;" alt="" />
</div>
<input type="file" οnchange="PreviewImage(this,'imgHeadPhoto','divPreview')" size="20"/>
<script type="text/javascript">
//js本地图片预览,兼容ie[6-9]、火狐、Chrome17+、Opera11+、Maxthon3
function PreviewImage(fileObj,imgPreviewId,divPreviewId){
var allowExtention=".jpg,.bmp,.gif,.png";//允许上传文件的后缀名document.getElementById("hfAllowPicSuffix").value;
var extention=fileObj.value.substring(fileObj.value.lastIndexOf(".")+1).toLowerCase();
var browserVersion= window.navigator.userAgent.toUpperCase();
if(allowExtention.indexOf(extention)>-1){
if(fileObj.files){//HTML5实现预览,兼容chrome、火狐7+等
if(window.FileReader){
var reader = new FileReader();
reader.onload = function(e){
document.getElementById(imgPreviewId).setAttribute("src",e.target.result);
}
reader.readAsDataURL(fileObj.files[0]);
}else if(browserVersion.indexOf("SAFARI")>-1){
alert("不支持Safari6.0以下浏览器的图片预览!");
}
}else if (browserVersion.indexOf("MSIE")>-1){
if(browserVersion.indexOf("MSIE 6")>-1){//ie6
document.getElementById(imgPreviewId).setAttribute("src",fileObj.value);
}else{//ie[7-9]
fileObj.select();
if(browserVersion.indexOf("MSIE 9")>-1)
fileObj.blur();//不加上document.selection.createRange().text在ie9会拒绝访问
var newPreview =document.getElementById(divPreviewId+"New");
if(newPreview==null){
newPreview =document.createElement("div");
newPreview.setAttribute("id",divPreviewId+"New");
newPreview.style.width = document.getElementById(imgPreviewId).width+"px";
newPreview.style.height = document.getElementById(imgPreviewId).height+"px";
newPreview.style.border="solid 1px #d2e2e2";
}
newPreview.style.filter="progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod='scale',src='" + document.selection.createRange().text + "')";
var tempDivPreview=document.getElementById(divPreviewId);
tempDivPreview.parentNode.insertBefore(newPreview,tempDivPreview);
tempDivPreview.style.display="none";
}
}else if(browserVersion.indexOf("FIREFOX")>-1){//firefox
var firefoxVersion= parseFloat(browserVersion.toLowerCase().match(/firefox\/([\d.]+)/)[1]);
if(firefoxVersion<7){//firefox7以下版本
document.getElementById(imgPreviewId).setAttribute("src",fileObj.files[0].getAsDataURL());
}else{//firefox7.0+
document.getElementById(imgPreviewId).setAttribute("src",window.URL.createObjectURL(fileObj.files[0]));
}
}else{
document.getElementById(imgPreviewId).setAttribute("src",fileObj.value);
}
}else{
alert("仅支持"+allowExtention+"为后缀名的文件!");
fileObj.value="";//清空选中文件
if(browserVersion.indexOf("MSIE")>-1){
fileObj.select();
document.selection.clear();
}
fileObj.outerHTML=fileObj.outerHTML;
}
}
</script>
</body>
</html>
淘宝不行,360 ie可以。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script type="text/javascript">
/**
* 从 file 域获取 本地图片 url
*/
function getFileUrl(sourceId) {
var url;
if (navigator.userAgent.indexOf("MSIE")>=1) { // IE
url = document.getElementById(sourceId).value;
} else if(navigator.userAgent.indexOf("Firefox")>0) { // Firefox
url = window.URL.createObjectURL(document.getElementById(sourceId).files.item(0));
} else if(navigator.userAgent.indexOf("Chrome")>0) { // Chrome
url = window.URL.createObjectURL(document.getElementById(sourceId).files.item(0));
}
return url;
}
/**
* 将本地图片 显示到浏览器上
*/
function preImg(sourceId, targetId) {
var url = getFileUrl(sourceId);
var imgPre = document.getElementById(targetId);
imgPre.src = url;
}
</script>
</head>
<body>
<form action="">
<input type="file" name="imgOne" id="imgOne" οnchange="preImg(this.id,'imgPre');" />
<img id="imgPre" src="" width="300px" height="300px" style="display: block;" />
</form>
</body>
</html>
input选择图片实现预览本地图片的方法,网上有很多,但是不能很好的兼容多种浏览器,这里找到一个兼容IE6、IE7、IE8和Chrome、firefox等浏览器的代码:还有360也可以,但淘宝不行。
<!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" >
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>本地图片预览</title>
<style type="text/css">
#preview{width:100px;height:100px;border:1px solid #000;overflow:hidden;}
#imghead {filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=image);}
</style>
<script type="text/javascript">
function previewImage(file)
{
var MAXWIDTH = 100;
var MAXHEIGHT = 100;
var div = document.getElementById('preview');
if (file.files && file.files[0])
{
div.innerHTML = '<img id=imghead>';
var img = document.getElementById('imghead');
img.onload = function(){
var rect = clacImgZoomParam(MAXWIDTH, MAXHEIGHT, img.offsetWidth, img.offsetHeight);
img.width = rect.width;
img.height = rect.height;
img.style.marginLeft = rect.left+'px';
img.style.marginTop = rect.top+'px';
}
var reader = new FileReader();
reader.onload = function(evt){img.src = evt.target.result;}
reader.readAsDataURL(file.files[0]);
}
else
{
var sFilter='filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=scale,src="';
file.select();
var src = document.selection.createRange().text;
div.innerHTML = '<img id=imghead>';
var img = document.getElementById('imghead');
img.filters.item('DXImageTransform.Microsoft.AlphaImageLoader').src = src;
var rect = clacImgZoomParam(MAXWIDTH, MAXHEIGHT, img.offsetWidth, img.offsetHeight);
status =('rect:'+rect.top+','+rect.left+','+rect.width+','+rect.height);
div.innerHTML = "<div id=divhead style='width:"+rect.width+"px;height:"+rect.height+"px;margin-top:"+rect.top+"px;margin-left:"+rect.left+"px;"+sFilter+src+"\"'></div>";
}
}
function clacImgZoomParam( maxWidth, maxHeight, width, height ){
var param = {top:0, left:0, width:width, height:height};
if( width>maxWidth || height>maxHeight )
{
rateWidth = width / maxWidth;
rateHeight = height / maxHeight;
if( rateWidth > rateHeight )
{
param.width = maxWidth;
param.height = Math.round(height / rateWidth);
}else
{
param.width = Math.round(width / rateHeight);
param.height = maxHeight;
}
}
param.left = Math.round((maxWidth - param.width) / 2);
param.top = Math.round((maxHeight - param.height) / 2);
return param;
}
</script>
</head>
<body>
<div id="preview">
<img id="imghead" width=100 height=100 border=0 src='../images/head01_big.jpg'>
</div>
<br/>
<input type="file" οnchange="previewImage(this)" />
</body>
</html>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "">
<html xmlns=""><head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>Firefox3,IE6,IE7,IE8上传图片预览</title>
<style type="text/css">
#preview_wrapper{
display:inline-block;
width:300px;
height:300px;
background-color:#CCC;
}
#preview_fake{ /* 该对象用户在IE下显示预览图片 */
filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=scale);
}
#preview_size_fake{ /* 该对象只用来在IE下获得图片的原始尺寸,无其它用途 */
filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=image);
visibility:hidden;
}
#preview{ /* 该对象用户在FF下显示预览图片 */
width:300px;
height:300px;
}
</style>
<script type="text/javascript">
function onUploadImgChange(sender){
if( !sender.value.match( /.jpg|.gif|.png|.bmp/i ) ){
alert('图片格式无效!');
return false;
}
var objPreview = document.getElementById( 'preview' );
var objPreviewFake = document.getElementById( 'preview_fake' );
var objPreviewSizeFake = document.getElementById( 'preview_size_fake' );
if( sender.files && sender.files[0] ){
objPreview.style.display = 'block';
objPreview.style.width = 'auto';
objPreview.style.height = 'auto';
// Firefox 因安全性问题已无法直接通过 input[file].value 获取完整的文件路径
objPreview.src = sender.files[0].getAsDataURL();
}else if( objPreviewFake.filters ){
// IE7,IE8 在设置本地图片地址为 img.src 时出现莫名其妙的后果
//(相同环境有时能显示,有时不显示),因此只能用滤镜来解决
// IE7, IE8因安全性问题已无法直接通过 input[file].value 获取完整的文件路径
sender.select();
var imgSrc = document.selection.createRange().text;
objPreviewFake.filters.item(
'DXImageTransform.Microsoft.AlphaImageLoader').src = imgSrc;
objPreviewSizeFake.filters.item(
'DXImageTransform.Microsoft.AlphaImageLoader').src = imgSrc;
autoSizePreview( objPreviewFake,
objPreviewSizeFake.offsetWidth, objPreviewSizeFake.offsetHeight );
objPreview.style.display = 'none';
}
}
function onPreviewLoad(sender){
autoSizePreview( sender, sender.offsetWidth, sender.offsetHeight );
}
function autoSizePreview( objPre, originalWidth, originalHeight ){
var zoomParam = clacImgZoomParam( 300, 300, originalWidth, originalHeight );
objPre.style.width = zoomParam.width + 'px';
objPre.style.height = zoomParam.height + 'px';
objPre.style.marginTop = zoomParam.top + 'px';
objPre.style.marginLeft = zoomParam.left + 'px';
}
function clacImgZoomParam( maxWidth, maxHeight, width, height ){
var param = { width:width, height:height, top:0, left:0 };
if( width>maxWidth || height>maxHeight ){
rateWidth = width / maxWidth;
rateHeight = height / maxHeight;
if( rateWidth > rateHeight ){
param.width = maxWidth;
param.height = height / rateWidth;
}else{
param.width = width / rateHeight;
param.height = maxHeight;
}
}
param.left = (maxWidth - param.width) / 2;
param.top = (maxHeight - param.height) / 2;
return param;
}
</script>
</head>
<body>
<div id="preview_wrapper">
<div id="preview_fake">
<img id="preview" οnlοad="onPreviewLoad(this)"/>
</div>
</div>
<br/>
<input id="upload_img" type="file" οnchange="onUploadImgChange(this)"/>
<br/>
<img id="preview_size_fake"/>
</body>
</html>