HTML5 – 文件上传

利用XMLHttpRequest快速实现无刷新上传文件。

利用FormData这个对象可以方便的使用表单内的数据,它有以下几个主要函数:

append : 想表单数据中追加某些数据

var fm = new FormData();
 fm.append('name', 'laokiea');

set  :  通过name值设置第一个对象的value值,如果不存在则新增一个

fm.append('name', 'laokiea');
 fm.set('name', 'bob');

 get  :  通过name值获取第一个对象的value值

fm.get('name')

我们使用该对象来上传图片:

var fileInput = document.getElementById("upload");
var formData = new FormData();
var xhr = new XMLHttpRequest();
var submit = document.getElementById("submit");

var file = fileInput.files;

for(var i = 0;i < files.length; i++) {
var file = files[i];
fm.append('files[]', file, file.name);
}

xhr.open('POST', 'upload.php', true);
xhr.send(fm);
xhr = null;

显示进度条,XMLHttpRequest有个upload属性,该属性有对应的onprogress方法,方法的事件对象有两个属性,分别是loaded和total,代表已上传的字节数和总字节数。用这两个值可以计算出进度。

// 显示进度
xhr.upload.onprogress = function(event) {
if (event.lengthComputable) {
var percentComplete = (event.loaded / event.total) * 100;
progress.value = percentComplete;
}
}

图片预览,可以使用FileReader对象,该对象有 readDataAsURL方法,可以将文件资源转换成以data:打头的URL资源。这里需要把reader对象放在循环里去实例化。

                         function preview() {
				var files = fileInput.files;
				for (var i = 0;i < files.length;i++) {
					var file = files[i];
					if(file.type != '' && /image\/\w+/.test(file.type)) {
						var reader = new FileReader();
						// 图片预览
						reader.onload = function(event) {
							var image = new Image();
							image.width = 100;
							image.src = this.result;
							document.body.appendChild(image);
						};
						reader.readAsDataURL(file);
					}
				}
			}

拖拽上传,主要实现ondragenter, ondragover, drop三个方法,分别表示,拖拽进来, 拖来拖去, 拖拽后,但是因为浏览器会自动打开拖拽的文件,所以要组织默认事件。

// 拖拽上传
			var holder = document.getElementById('holder');
			holder.ondragenter = function(e) {
				e.stopPropagation();
				e.preventDefault();
			}
			holder.ondragover = function(e) {
				e.stopPropagation();
				e.preventDefault();
			}
			holder.ondrop = function(e) {
				e.stopPropagation();
				e.preventDefault();
				window.files = e.dataTransfer.files;
				preview();
			}

 

总的代码:

<html charset='utf-8'>
<head>
	<title>upload</title>
	<style type="text/css">
		html,body{width:100%;}
		#holder {
			border: 10px dashed #000;
			width:  300px;
			height: 300px;
			min-height: 300px;
			margin: 20px auto;
		}
		#holder.hover {
			border: 10px dashed #0c0;
		}
	</style>
</head>
<body>
		<input type='file' id='upload' onchange='preview()' multiple/>
		<input type='submit' id='submit' value='ok'/>
		<progress id='progress' value=0 max=100></progress>
		<div id="holder"></div>
		<script>
			var fileInput = document.getElementById("upload");
			var formData = new FormData();
			var xhr = new XMLHttpRequest();
			var submit = document.getElementById("submit");
			var progress = document.getElementById("progress");

			function preview() {
				var files = fileInput.files;
				for (var i = 0;i < files.length;i++) {
					var file = files[i];
					if(file.type != '' && /image\/\w+/.test(file.type)) {
						var reader = new FileReader();
						// 图片预览
						reader.onload = function(event) {
							var image = new Image();
							image.width = 100;
							image.src = this.result;
							document.body.appendChild(image);
						};
						reader.readAsDataURL(file);
					}
				}
			}

			// 拖拽上传
			var holder = document.getElementById('holder');
			holder.ondragenter = function(e) {
				e.stopPropagation();
				e.preventDefault();
			}
			holder.ondragover = function(e) {
				e.stopPropagation();
				e.preventDefault();
			}
			holder.ondrop = function(e) {
				e.stopPropagation();
				e.preventDefault();
				window.files = e.dataTransfer.files;
				preview();
			}

			submit.onclick = function() {
				files = fileInput.files;
				for (var i = 0;i < files.length;i++) {
					var file = files[i];
					formData.append('files[]',file, file.name);
				}
				// xhr.onreadystatechange = function(){
				// 	console.log(this.readyState);
				// }

				xhr.open("POST","upload.php",true);

				//xhr.onload = function() {
				// if(this.status == 200) {
				// 		alert(this.response);
				// 	}
				// }

				// 显示进度
				xhr.upload.onprogress = function(event) {
					if (event.lengthComputable) {
        				var percentComplete = (event.loaded / event.total) * 100;
        				progress.value = percentComplete;
    				}
				}

				xhr.send(formData);
				xhr = null;
			}

		</script>
</body>
</html>

参考文章:

https://segmentfault.com/a/1190000006716454

http://www.helloweba.com/view-blog-192.html

https://www.qcloud.com/community/article/985614?fromSource=gwzcw.114038.114038.114038

http://www.ruanyifeng.com/blog/2012/08/file_upload.html

每日总结:jquery的ajax以及阻止默认事件

今天该bug,遇到一个情况,有一个修改按钮,按钮是有href属性的,在点按钮之前需要向后端请求一下,后端会返回一个标识,然后根据这个标识判断是否要跳转。

刚开始是想在回调里判断标识,如果失败阻止默认事件,并做接下来的处理,但是一直行不通。后来改成点击的时候就阻止,成功了,代码如下:

$(".edit").on("click", function(event){
          event.preventDefault();
          var url = createLink('order', 'checkSaleBeforeEdit', 'id=' + v.orderID);
          var _this = $(this);
          var href = _this.attr('href');
          $.ajax({
            'url':url,
            'type':'post',
            'dataType':'json',
            success:function(data){
              if(data.result == 'fail'){
                alert(v.cantEdit);
                history.go(0);
              }else{
                location.href = href;
              }
            }
          });
      });
    }

过程中还遇到一个问题,本以为回调函数里的作用域跟on函数的作用域不一样,想着变量通过参数传入,后来查资料发现不用,可以直接传入。