js多圖片上傳
阿新 • • 發佈:2018-11-28
Multi多圖片上傳
這兩天用原生徒手擼了個外掛,寫的不是很完美,在這裡先介紹一下傳統的面向過程的javascript寫法,還有很多不足,希望多多指正
使用到的技術
- 使用formDate物件:更靈活操作需要傳送的表單檔案
- 使用FileReader物件:允許web應用程式非同步操作本地檔案
- FileReader.readAsDataURL()將讀取的檔案轉換為base64編碼的字串
- FileReader.onload()檔案讀取時觸發該方法
- FileReader.onerror()檔案讀取錯誤時觸發該方法
可以參考MDN提供的API https://developer.mozilla.org/zh-CN/docs/Web/API/FileReader
關鍵函式
1.檔案變動操作
//onchange只有在檔案發生改動的時候會呼叫
inputFile.onchange = function(){
progress = {value:0,count:this.files.length};
for (var i = 0; i < this.files.length; i++)readerFile(this.files,i);
}
2.檔案非同步讀取
function readerFile(files,index){
var reader = new FileReader();
var currFile =files[index];
reader.readAsDataURL(currFile);
if (checkFile(currFile,5)){
reader.onload = function(e){
currFile.result = e.target.result;
fileData.push({ //格式整理
name:currFile.name,
type:currFile.type,
size:currFile.size,
lastModified:currFile.lastModified,
result:currFile.result
});
createDOM(currFile)
progress.value+=1 ;
var num = progress.value/progress.count*100;
if(progress.value>=progress.count){
console.log(fileData.length+'個檔案已全部讀取完成!');
}
}
reader.onerror = function(){
console.log("檔案上傳失敗!");
}
}
}
3.檔案上傳
uploadBtn.onclick = function(){
formData = new FormData(formDom);
formData.set("files",JSON.stringify(fileData));
console.log(formData)
//封裝完成 暫無介面測試
ajax({
url:"",
type:"POST",
data:formData,
success:function(){
console.log("上傳成功")
},
error:function(){
console.log("上傳失敗")
}
})
}
4.檔案格式、大小、數量、重複等檢測
function checkFile(currFile,max){
var isLegal = true;
if(['image/png','image/jpeg','image/jpg','image/gif'].indexOf(currFile.type)==-1){
console.log('檔案型別只允許:png、jpg、gif');
isLegal = false;
}
if(currFile.size > 2048*1024){
console.log('檔案大小超出限制,最大允許 2 MB');
isLegal = false;
}
if(fileExists(currFile.name+currFile.lastModified)){
console.log(currFile.name+",檔案重複");
isLegal = false;
}
if(fileData.length>=max){
console.log('檔案數量超出,最多上傳'+max+'張圖片');
isLegal = false;
}
return isLegal;
}
5.檔案去重(通過檔名和檔案修改時間判斷)
function fileExists(checkFlag){
var isRepeat = false;
console.log(fileData)
fileData.forEach(function(f){
if(f.name + f.lastModified === checkFlag)isRepeat = true;
});
return isRepeat;
}
6.建立圖片縮圖(縮圖點選刪除)(可省略)
我這裡是為了更直觀地看到上傳效果
function createDOM(currFile){
var img = new Image();
img.src = currFile.result;
var li = document.createElement("li");
li.appendChild(img);
ul.appendChild(li);
li.key = currFile.name + currFile.lastModified; //給每個縮圖一個標識
li.addEventListener("click",function(){
var _li = this; //標識當前li元素
ul.removeChild(this);
fileData.forEach(function(f,i){
if(f.name+f.lastModified == _li.key)fileData.splice(i,1);
})
})
}
7.上傳操作(ajax封裝)
這裡只做post的封裝
function ajax(options){
var defaultOptions = {
url:"",
type:"",
data:null,
dataType:"json",
success:function(){},
error:function(){}
}
options = Object.assign({},defaultOptions,options);
if(window.XMLHttpRequest){
var xhr = new XMLHttpRequest();
}else{
var xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
if(xhr.status === 200){
options.success();
}else{
options.error();
}
}
}
xhr.open(options.type,options.url,true);
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=utf-8");
xhr.send(options.data);
}
以上的程式碼是全部的js邏輯,如果想更直觀地看到效果,可將下面的html+css程式碼進行ctrl+v
/*css*/
<style type="text/css">
*{padding:0;margin:0;}
form{padding: 30px;width: 500px;margin: 200px auto 0;box-shadow: 0 3px 20px #ddd;}
input{display: none;}
span#addBtn{display: inline-block;padding: 25px;background: #00A09D;border-radius: 5px;color: white;position: relative;}
span#addBtn::after,span#addBtn::before{content:"";width: 25px;height: 3px;background: #fff;position: absolute;top: 0;left:0;bottom: 0;right: 0;margin: auto;}
span#addBtn::before{transform: rotate(90deg);}
div#uploadBtn{width: 150px;margin: 20px auto 0;text-align: center;color: #fff;background: #00A09D;border-radius: 5px;padding: 10px 0;}
ul.file-box{list-style: none;margin: 30px 0;}
ul.file-box::after{display: block;content: "";clear: both;}
ul.file-box li{float: left;width: 18%;margin: 10px 1% 0;border-radius: 5px;overflow: hidden;text-align: center;box-shadow: 0 3px 20px #aaa;}
ul.file-box li img{width: 90px;height:90px;vertical-align: middle;}
/*動畫樣式*/
.shake-btn:hover{animation: shake .5s;}
.bigger-btn:hover{animation: bigger .4s;}
@keyframes shake{
0%{transform: rotate(0deg);}
25%{transform: rotate(5deg);}
50%{transform: rotate(-10deg);}
75%{transform: rotate(5deg);}
100%{transform: rotate(0);}
}
@keyframes bigger{
0%{transform: scale(1);}
49%{transform: scale(1.1);}
51%{transform: scale(1.1);}
100%{transform: scale(1);}
}
</style>
<!-- html -->
<form action="" id="fileForm" method="post">
<!--新增圖片按鈕 start-->
<label>
<input type="file" name="files" multiple accept="image/jpeg,image/png,image/gif"/>
<span id="addBtn" class="bigger-btn"></span>
</label>
<!--新增圖片按鈕 end-->
<!--圖片縮圖列表 start-->
<ul class="file-box"></ul>
<!--圖片縮圖列表 end-->
<!--上傳按鈕 start-->
<div id="uploadBtn" class="shake-btn">上傳圖片</div>
<!--上傳按鈕 end-->
</form>
好像有點多啊,這是我初步的程式碼,封裝好的完整的程式碼在我的github上
有興趣的可以去看看,大家多多批評
https://github.com/mqr123/tools/blob/master/Multi/Multi-picture-uploading.js