首页 > 代码库 > Ajax文件上传组件

Ajax文件上传组件

    项目中经常需要文件上传,每次都要重复造轮子,所以决定将文件上传做成组件,方便使用。效果如图:

技术分享

    自我感觉效果还是可以的,而且使用的代码也变得十分清晰,前端的html代码非常简洁,如下:

<html>
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
	<link href = "fileuploader.css" rel="stylesheet"/>

	<script src = "fileuploader.js"></script>
</head>
<body>
	<div id = "imageList"></div>
</body>
<script>
	var fileWidget = null;
	(function(){
		var imageList = document.getElementById("imageList");
		fileWidget = new FileWidgt(imageList);
		fileWidget.newPlaceholder({url:"http://127.0.0.1:8000/App/upload.php"});
	})();
</script>
</html>

       前端代码只需新建一个FileWidgt类,然后调用newPlaceholder方法即可,所有复杂的操作都封装到FileWidgt类中。接下来主要分析FileWidgt类。

    首先先看一下该组件的结构图:

技术分享

    根据结构图编写代码:

function FileWidgt(ui){
	this.ui = ui;
	this.data = "";//记录选中且已经上传并返回的结果
	this.files = [];//用于记录已选中的文件,防止重复上传
}

FileWidgt.prototype.newPlaceholder = function(s){
	var fileholder = document.createElement("input");//内部隐藏的输入框
	fileholder.setAttribute("type","file");
	fileholder.setAttribute("name","file");
	var placeholder = document.createElement("div");//显示图片的容器
	placeholder.setAttribute("class","image-item space");
	var closeButton = document.createElement(‘div‘);//关闭按钮
	closeButton.setAttribute("class","image-close");
	closeButton.innerHTML = ‘X‘;
	placeholder.appendChild(fileholder);
	placeholder.appendChild(closeButton);
	this.ui.append(placeholder);//显示图片的容器加入最外层容器
	var that = this;
	closeButton.addEventListener(‘click‘,function(event){
		event.stopPropagation();
		event.cancelBubble = true;
		setTimeout(function(){
			that.data = that.data.replace(placeholder.getAttribute("image-data"),"");//data中去除该关闭的图片结果
			that.data = that.data.replace(",,",",");
			if(that.data.length > 0 && that.data.charAt(0) == ","){
				that.data = that.data.substring(1);
			}else if(that.data.length > 0 && that.data.charAt(that.data.length - 1) == ","){
				that.data = that.data.substring(0,that.data.length - 1);
			}
			that.ui.removeChild(placeholder);//去除关闭的显示容器
		},0);
	},false);
	placeholder.addEventListener("click",fileholder.onclick,false);//点击调用文件上传
	fileholder.addEventListener("change",function(e){//选中文件后上传图片
		if(that.files.join(",").indexOf(fileholder.value) == -1){
			
			var formData = new FormData();
			formData.append("file",fileholder.files[0]);
			var xhr = null;
			if(window.ActiveXObject){
				xhr = new ActiveXObject("Microsoft.XMLHTTP");
			}else{
				xhr = new XMLHttpRequest();
			}
			
			
			xhr.open(s.method||‘POST‘,s.url,true);
	
			
			xhr.onreadystatechange  = function(){//Ajax文件上传返回
				if(xhr.readyState == 4 && xhr.status == 200){
					var filename = JSON.parse(xhr.responseText).filename;
					placeholder.style.backgroundImage = ‘url(‘+filename+‘)‘;//替换当前添加图片为上传文件的图片
					if(placeholder.getAttribute("image-data") == undefined ||placeholder.getAttribute("image-data") == ""){
						placeholder.classList.remove(‘space‘);
						placeholder.removeEventListener("click",fileholder.onclick,false);
						placeholder.removeChild(fileholder);
						that.newPlaceholder(s);//新建一个添加的图标
					}
					//给data值添加当前上传的文件地址
					if(that.data == ""){
						that.data = filename;
						placeholder.setAttribute("image-data",filename);
					}else{
						that.data += "," + filename;
						placeholder.setAttribute("image-data",filename);
					}
				}
			}
			xhr.send(formData);
		}
	},false);
}
FileWidgt.prototype.getData = function(){
	return this.data;
}

      样式代码:

.image-item {
width: 65px;
height: 65px;
background-image: url(img/iconfont-tianjia.png);
background-size: 100% 100%;
display: inline-block;
position: relative;
border-radius: 5px;
margin-right: 10px;
margin-bottom: 10px;
border: solid 1px #e8e8e8;
}
.image-item input[type="file"] {
position: absolute;
left: 0px;
top: 0px;
width: 100%;
height: 100%;
opacity: 0;
cursor: pointer;
z-index: 0;
}
.image-item .image-close {
position: absolute;
display: inline-block;
right: -6px;
top: -6px;
width: 20px;
height: 20px;
text-align: center;
line-height: 20px;
border-radius: 12px;
background-color: #FF5053;
color: #f3f3f3;
border: solid 1px #FF5053;
font-size: 9px;
font-weight: 200;
z-index: 1;
}
.image-item.space .image-close {
display: none;
}

      后台代码:

<?php
	header("Access-Control-Allow-Origin:*");
	file_put_contents("log.log",$_FILES[‘file‘][‘name‘]);
	move_uploaded_file($_FILES[‘file‘][‘tmp_name‘],‘upload/‘.$_FILES[‘file‘][‘name‘]);
	echo json_encode(array("filename"=>‘http://‘.$_SERVER["REMOTE_ADDR"].‘:‘.$_SERVER["SERVER_PORT"].‘/App/upload/‘.$_FILES[‘file‘][‘name‘]));

?>

说明:后台代码对中文名称文件没有做操作,大家可以用自己喜欢的语言做后台代码。


本文出自 “走一停二回头看三” 博客,请务必保留此出处http://janwool.blog.51cto.com/5694960/1897696

Ajax文件上传组件