一直以来在网页中上传图片都使用的原始的 input type=file ,样子很丑,而且只能显示图片的名称,无法预览,今天自己动手写了一个组件,并美化了一下。
样式的实现原理就是网上流行的隐藏input控件透明度opacity=0的办法,图片的预览实现原理使用了javascript里的createObjectURL方法。
一、css 部分:
.list { padding: 10px;}
.list:after { content: ""; display: block; clear: both; height: 0; line-height: 0; font-size: 0;}
.list li { position: relative; float: left; width: 60px; height: 60px; margin-right: 10px; border: 1px solid #ccc;}
.list li:before { content: ""; position: absolute; top: 50%; left: 50%; width: 30px; height: 1px; margin-top: -1px; margin-left: -15px; background-color: #ccc;}
.list li:after { content: ""; position: absolute; top: 50%; left: 50%; width: 1px; height: 30px; margin-top: -15px; margin-left: -1px; background-color: #ccc;}
.list li img { position: relative; z-index: 2; display: block; width: 100%; height: 100%;}
.list input[type="file"] { position: absolute; left: 0; top: 0; z-index: 3; display: block; width: 100%; height: 100%; cursor: pointer; opacity: 0;}
二、html 部分:
<ul class="list">
<li>
<input type="file" onchange="handleFiles(this.files,this.parentNode)">
</li>
<li>
<input type="file" onchange="handleFiles(this.files,this.parentNode)">
</li>
<li>
<input type="file" onchange="handleFiles(this.files,this.parentNode)">
</li>
</ul>
*注:this.files,this.parentNode 是2个必须的参数,传递给所调用的函数当前点击的元素的参数。
this.files 是当前选择的图片路径
this.parentNode 是找到当前input元素的父节点li
完成后的样子如下图:
三、js 部分:
<script>
//构建预览上传图片的函数,并接收传递过来的2个变量参数
function handleFiles(file,obj) {
//获取当前点击的元素的所有同级元素的html内容
var con = obj.innerHTML;
//判断当前点击元素内是否已经存在img图片元素,如果有则先全部清除后再添加,如果没有就直接添加
if (con.indexOf("img") > 0) {
var pic = obj.getElementsByTagName("img");
for (var i=0; i<pic.length; i++) {
obj.removeChild(pic[i]);
}
//调用添加img图片的函数
creatImg();
} else {
creatImg();
}
function creatImg() {
//创建一个img元素
var img = document.createElement("img");
//设置img元素的源文件路径,window.URL.createObjectURL() 方法会根据传入的参数创建一个指向该参数对象的URL. 这个URL的生命仅存在于它被创建的这个文档里
img.src = window.URL.createObjectURL(file[0]);
//window.URL.revokeObjectURL() 释放一个通过URL.createObjectURL()创建的对象URL,在图片被显示出来后,我们就不再需要再次使用这个URL了,因此必须要在加载后释放它
img.onload = function() {
window.URL.revokeObjectURL(this.src);
}
//在当前点击的input元素后添加刚刚创建的img图片元素
obj.appendChild(img);
}
}
</script>