实现图片本地预览

思路:
    1. 监听input[type=file]的变化,一旦触发则开启显示事件。
    2. 读取file对象,检查类型。
    3. 新建image节点,添加到展示区域
    4. 新建FileReader对象,读取图片文件并将其添加到image的src
1
2
<input type="file" name="image" id="image" accept="image/png,image/jpeg">
<div class="display" id="display"></div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var fileInput = document.getElementById("image")
fileInput.onchange = function(event){
if (this.files.length == 0) { return }
var oFile = this.files[0]
if (!/image.*/.test(oFile.type)) {return}
var img = document.createElement("img")
document.getElementById("display").appendChild(img)
var reader = new FileReader();
reader.onload = function(evt) {
img.src= evt.target.result;
}
reader.readAsDataURL(oFile)
// 或者用createObjectURL
img.src = window.URL.createObjectURL(file)
}

以上方法兼容Chrome、火狐、IE edge及IE10。IE10以下并不兼容,以下为兼容版本。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
//下面用于图片上传预览功能
var imgInput = document.getElementById("imgInput")
var imgPreview = document.getElementById("preview")
imgInput.onchange = function(event){
if (imgInput.files && imgInput.files[0]) {
var file = imgInput.files[0]
// createObjectURL 方法同步,内存占用少,网页关闭或使用revokeObjectURL时释放
imgPreview.src = window.URL.createObjectURL(file)
// readAsDataURL 方法异步,内存占用多,垃圾回收
// var read = new FileReader();
// read.onload = function(event) {
// imgPreview.src = event.target.result
// }
// read.readAsDataURL(file)
} else {
// IE10以下兼容
var imgSrc = imgInput.value
var localImag = document.getElementById("localImag");
try {
localImag.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=scale)";
localImag.filters.item("DXImageTransform.Microsoft.AlphaImageLoader").src = imgSrc;
} catch(e) {
alert("您上传的图片格式不正确,请重新选择!");
return false;
}
imgPreview.style.display = 'none';
}
}

有一个问题:为什么不能直接将imgInput的value值赋给展示区域imgPreview的src属性呢?
答:当我们通过input上传图片时,因为浏览器的沙箱机制,将可能包含敏感信息的真实图片路径给隐藏了起来,例如用”c:/fakepath/a.png”代替原路径,因此此时inputd的value值并不能正确连接到图片文件。而通过IE的滤镜、FileReader、Blob都可以获取图片的真实路径,只是实现方法不一样。