帶進度條的多文件上傳demo

2019年春節過完,剛來上班第一天,沒啥事情,就做了這麼個多文件上傳的demo,方便以後有這方面需求,可以作爲參考。

一、先貼幾張效果圖:

1、頁面初始化:

在這裏插入圖片描述

2、選擇文件效果:

在這裏插入圖片描述

3、上傳文件效果:

在這裏插入圖片描述

二、代碼

1、html+js部分代碼
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8" />
	<script type="text/javascript" src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
	<title>多文件帶進度條上傳</title>
	<style type="text/css">
		*{
			font-family: 'microsoft yahei';
			color: #4A4A4A;
		}
		.upload{
			width: 750px;
			padding: 15px;
			border: 1px dashed #ccc;
			margin: 25px auto;
			border-radius: 5px;
		}    
		.uploadBox{
			width: 100%;
			height: 35px;
			/*background: #F0F0F0;*/
			position: relative;
		}
		.uploadBox input{
			height: 30px;
			background: red;
			position: absolute;
			top: 2px;
			left: 0;
			z-index: 201;
			opacity: 0;
			cursor: pointer;
		}
		.uploadBox .inputCover{
			width: 100px;
			height: 30px;
			position: absolute;
			top: 2px;
			left: 0;
			z-index: 200;
			text-align: center;
			line-height: 30px;
			font-size: 14px;
			border: 1px solid #009393;
			border-radius: 5px;
			cursor: pointer;
		}
		.uploadButton{
			width: 100px;
			height: 30px;
			position: absolute;
			left: 65%;
			border-radius: 5px;
			border: 1px solid #ccc;
			background: #F0F0F0;
			outline: none;
			cursor: pointer;
		}
		.uploadButton:hover{
			background: #E0E0E0;
		}
		.processBar{
			display: inline-block;
			width: 0;
			height: 7px;
			position: absolute;
			left: 600px;
			top: 14px;
			background: #009393;
		}
		.processNum{
			position: absolute;
			left: 650px;
			color: #009393;
			font-size: 12px;
			line-height: 35px;
		}
		.delFile{
			width:40px;
			position: absolute;
			left: 715px;
			color: red;
			font-size: 12px;
			height:30px;
			line-height: 30px;
			border-radius: 5px;
			text-align: center;
			border: 1px solid red;
			cursor:pointer;
		}
		.show{
			text-align: center;
			font-size: 14px;
			color: #4A4A4A;
		}
		.fileInfo{
			min-width: 200px;
			height: 30px;
			position: absolute;
			top: 2px;
			margin-left:150px;
			text-align: center;
			line-height: 30px;
			font-size: 14px;
			border-radius: 5px;
		}
		.cancelFile{
			width: 50px;
			height: 30px;
			position: absolute;
			top: 2px;
			margin-left:500px;
			text-align: center;
			line-height: 30px;
			font-size: 14px;
			border: 1px solid red;
			color:red;
			border-radius: 5px;
			text-decoration:none;
			display:none;
		}
		.addFile{
			width: 80px;
			height: 30px;
			position: relative;
			margin-bottom:15px;
			left: 66%;
			border-radius: 5px;
			border: 1px solid #afdfd0;
			text-align: center;
			line-height:30px;
			color:#00bb80;
			background: #e8f8f3;
			font-size:14px;
			cursor:pointer;
		}
	</style>
</head>
<body>
	<div class="addFile">添加文件</div>
	<div class="upload">
		<div class="uploadBox">
			<span class="inputCover">選擇文件</span>
			<span class="fileInfo"></span>
			<a href="javascript:void(0);" class="cancelFile">取消</a>
			<form enctype="">
				<input type="file" name="file" class="file"/>
			</form>
			<span class="processBar"></span>
			<span class="processNum">未選擇文件</span>
		</div>
	</div>
	<button type="button" class="uploadButton">上傳</button>
	<div class="show"></div>
</body>
<script>
$(document).ready(function(){
    var num = 0;
	var uploadNum = 0;
	var errorInfo = '';
	var filetypes =["jpg", "png", "gif", "jpeg", "mp3", "flv", "avi", "mp4", "doc", "docx", "txt", "xlsx", "xls", "ppt", "pptx", "pdf", "wgt"];

	//選擇文件時,相關事件
	$(document).on('change','input[type=file]',function(){
		var filemaxsize = 1024*1024*1024;//1G,最大上傳限制
		var isIE = /msie/i.test(navigator.userAgent);//判斷是否是ie瀏覽器
		var fileSize = 0;
		var filePath=$(this).val();
		if (isIE && !this.files) {
			var filePath = this.value;
			var fileSystem = new ActiveXObject("Scripting.FileSystemObject");
			if(!fileSystem.FileExists(filePath)){
				alert("附件不存在,請重新選擇!");
				return false;
			}
			var file = fileSystem.GetFile (filePath);
			fileSize = file.Size;
		} else {
			if(this.files.length > 0){
				fileSize = this.files[0].size;
			}else{
				return false;
			}
		}
		//判斷文件類型
		var isnext = false;
		var fileEnd = filePath.substring(filePath.indexOf(".")+1).toLowerCase();
		for(var i =0; i<filetypes.length;i++){
		  if(filetypes[i]==fileEnd){
			  isnext = true;
			  break;
		  }
		}
		if(!isnext){
          alert("您未上傳文件,或者您上傳文件類型有誤!");
          return false;
		}
		if(fileSize > filemaxsize){
			inputCover.html("<font>文件大於1G,請重新選擇</font>");
			processNum.html('未選擇文件');
			filePath = '';
			return false;
		}else{
			$(this).parent().parent().find('.inputCover').html('重新選擇');
			$(this).parent().parent().find('.fileInfo').html(this.files[0].name+' / '+parseInt(fileSize/1024)+'KB');
			$(this).parent().parent().find('.cancelFile').show();
			$(this).parent().parent().find('.processNum').html('等待上傳');
		}
	});
	
	//取消文件事件
	$(document).on('click','.cancelFile',function(){
        $(this).parent().find('.file').val(null); 
		$(this).parent().find('.inputCover').html('選擇文件');
		$(this).parent().find('.fileInfo').html('');
		$(this).parent().find('.cancelFile').hide();
		$(this).parent().find('.processNum').html('未選擇文件');
    });
	
	//新增文件事件
	$(document).on('click','.addFile',function(){
		if(num > 3){
			alert('最多上傳5個文件');
			return false;
		}
		var html = '';
		html += '<div class="uploadBox">';
		html += '<span class="inputCover">選擇文件</span>';
		html += '<span class="fileInfo"></span>';
		html += '<a href="javascript:void(0);" class="cancelFile">取消</a>';
		html += '<form enctype="">';
		html += '<input type="file" name="file" class="file"/>';
		html += '</form>';
		html += '<span class="processBar"></span>';
		html += '<span class="processNum">未選擇文件</span>';
		html += '<span class="delFile">刪除</span>';
		html += '</div>';
		$('.upload').append(html);
		num++;
    });
	
	//刪除文件事件
	$(document).on('click','.delFile',function(){
		$(this).parent().remove();
		num--;
	});
	
	$(document).on('click','.uploadButton',function(){
		upload();
	})

	//創建ajax對象,發送上傳請求
	function upload(){
		//由於在success中用了延遲,導致當num<0時會再次執行upload函數
		if(num < 0){
			return false;
		}
		var paramData = new FormData();
		var filesInfo = $(".upload").children('.uploadBox').eq(uploadNum).find('.file')[0].files;
		if(filesInfo.length == 0){
			paramData.append('Filedata','');
		}else{
			paramData.append('Filedata',filesInfo[0]);
		}
		$.ajax({
			type: "post",
			url:'upload.php',
			data:paramData,
			cache:false,
			async:true,
			processData: false,
			contentType: false,
			xhr:function(){
				var myXhr = $.ajaxSettings.xhr();
				if(myXhr.upload){
					myXhr.upload.addEventListener('progress',function(e){                
						var loaded = e.loaded;
						var total = e.total;
						var percent = Math.floor(100*loaded/total);
						if(percent == 100){
							percent = 99;
						}
						if(filesInfo.length != 0){
							$(".upload").children('.uploadBox').eq(uploadNum).find('.processNum').html(percent+"%");
							$(".upload").children('.uploadBox').eq(uploadNum).find('.processBar').css("width",(percent/2)+"px");
						}
						                                                           
					}, false);
				}
				return myXhr;
			},
			success: function(data){
				if(data.code == 1){
					$(".upload").children('.uploadBox').eq(uploadNum).find('.processNum').html("100%");
					$(".upload").children('.uploadBox').eq(uploadNum).find('.processBar').css("width","50px");
				}else{
					errorInfo += '第'+(uploadNum+1)+'個'+data.msg+"\n";
				}
				uploadNum++;
				num--;
				if(num < 0){
					if(errorInfo != ''){
						//延遲200ms執行,等渲染完成
						window.setTimeout(function () {
							alert(errorInfo);
							location.reload();
							return false;
						}, 200);
					}else{
						//延遲200ms執行,等渲染完成
						window.setTimeout(function () {
							alert('全部上傳成功!');
							location.reload();
							return false;
						}, 200);
					}
				}
				upload();
			}
		})
	}
})
</script>
</html>
2、php部分代碼
<?php
header('Content-Type:application/json; charset=utf-8');  
if(!empty($_FILES["Filedata"])){
	$fileParts = pathinfo($_FILES['Filedata']['name']);
	if($_FILES['Filedata']['size']/(1024*1024)>1024){
		$re['code'] = 4;
		$re['msg'] = '文件大小超過1G!';
		exit(json_encode($re));
	}
	$filetypes = array("jpg", "png", "gif", "jpeg", "mp3", "flv", "avi", "mp4", "doc", "docx", "txt", "xlsx", "xls", "ppt", "pptx", "pdf", "wgt");
	if(!in_array(strtolower($fileParts['extension']),$filetypes)){
		$re['code'] = 4;
		$re['msg'] = '文件格式不支持!';
		exit(json_encode($re));
	}
	$targetFolder = './uploads';
	if(!is_dir($targetFolder)){  //如果不存在該文件夾
		mkdir($targetFolder, 0777);  //創建文件夾
		chmod($targetFolder, 0777);  //改變文件模式
	}
	$res = move_uploaded_file($_FILES["Filedata"]["tmp_name"],"uploads/".$_FILES["Filedata"]["name"]);
    if($res){
		$re['code'] = 1;
		$re['msg'] = '上傳成功';
	}else{
		$re['code'] = 2;
		$re['msg'] = '上傳失敗';
	}
}else{
    $re['code'] = 3;
	$re['msg'] = '請選擇上傳文件';
}
exit(json_encode($re));

三、優化

js和php部分都是採用的面向過程寫法,主要是爲了以後參考,以後有時間,會將js部分改成面向對象寫法。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章