访问选中的文件
简单的html代码:
<input type="file" id="input">
通过File API,我们可以在用户选取一个或者多个文件之后(如果你的程序可以让用户选择多个文件,记得要在input元素上加上multiple属性),访问到代表了所选文件的一个或多个File对象,这些对象被包含在一个FileList对象中.
如果用户只选择了一个文件,那么我们只需要访问这个FileList对象中的第一个元素.
可以使用传统的DOM选择方法来获取到用户所选择的文件:
var selected_file = document.getElementById("input").files[0];
也可以使用jquery选择器来选择:
var selected_file = $("#input").get(0).files[0];
获取所选文件的信息
用户所选择的文件都存储在了一个FileList对象上,其中每个文件都对应了一个File对象.你可以通过这个FileList对象的length属性知道用户一共选择了多少个文件:
var numFiles = files.length;
可以通过一个for循环语句来操作每个单独的File对象:
for (var i = 0, numFiles = files.length; i < numFiles; i++) {
var file = files[i];
..
}
File对象上有三个属性提供了所包含文件的相关信息.
。name
文件名,只读字符串,不包含任何路径信息.
。size
文件大小,单位为字节,只读的64位整数.
。type
MIME类型,只读字符串,如果类型未知,则返回空字符串.
在change事件发生时读取所选择的文件
<input type="file" id="input" multiple accept="image/*" onchange="handleFiles(this.files)">
// accept="image/*"规定在文件上传中服务器只接受图像文件
动态添加change事件监听器
var inputElement = document.getElementById("inputField");
inputElement.addEventListener("change", handleFiles, false);
function handleFiles() {
var fileList = this.files,nBytes = 0;
for (var i = 0, numFiles = files.length; i < numFiles; i++) {
var file = files[i];
nBytes += file [i].size;
}
}
改变上传按钮样式
主流浏览器中,只需要使用样式display:none或者opacity:0把原本的文件输入框隐藏掉,然后在需要的时候调用它的click()方法就行了.
为自定义的按钮绑定click事件:
fileSelect.addEventListener("click", function (e) {
if (fileElem) {
fileElem.click();//触发隐藏的input file
}
e.preventDefault(); // prevent navigation to "#"
}, false);
通过拖放操作选择文件
重要的三个事件:dragenter, dragover,和drop;
//创建一个拖放操作的目的区域:
var dropbox;
dropbox = document.getElementById("dropbox");
dropbox.addEventListener("dragenter", dragenter, false);
dropbox.addEventListener("dragover", dragover, false);
dropbox.addEventListener("drop", drop, false);
//阻止dragenter和dragover事件的默认行为,这样才能触发drop事件
function dragenter(e) {
e.stopPropagation();
e.preventDefault();
}
function dragover(e) {
e.stopPropagation();
e.preventDefault();
}
//drop
function drop(e) {
e.stopPropagation();
e.preventDefault();
var dt = e.dataTransfer;
var files = dt.files;
//从事件对象中获取到dataTransfer对象,把该对象包含的Filelist对象传入函数handleFiles,这个函数会无区别的对待从input元素或拖放操作中来的文件列表.
handleFiles(files);
}
//handleFiles函数
function handleFiles(files) {
for (var i = 0; i < files.length; i++) {
var file = files[i];
var imageType = /image.*/;
if (!file.type.match(imageType)) {//是否是一个图像文件
continue;
}
var img = document.createElement("img");
img.classList.add("obj");//每张图片添加一个obj类,方便在DOM树找到
img.file = file;//添加了一个file属性来确认每张图片的 File,这样可以帮助我们在之后真正的上传工作时获取到图片
preview.appendChild(img);//把缩略图添加到预览区域
//处理图片的异步加载
var reader = new FileReader();//创建新的FileReader对象
reader.onload = (function(aImg) {
return function(e) {
aImg.src = e.target.result; };
})(img);
reader.readAsDataURL(file);
}
}
使用对象URL来显示图片
两个DOM方法:window.URL.createObjectURL()和 window.URL.revokeObjectURL()
window.URL = window.URL || window.webkitURL;
function handleFiles(files) {
if (!files.length) {
fileList.innerHTML = "<p>No files selected!</p>";
} else {
var list = document.createElement("ul");
for (var i = 0; i < files.length; i++) {
var li = document.createElement("li");
list.appendChild(li);
var img = document.createElement("img");
img.src = window.URL.createObjectURL(files[i]);
img.height = 60;
img.onload = function(e) {
window.URL.revokeObjectURL(this.src);
}
li.appendChild(img);
var info = document.createElement("span");
info.innerHTML = files[i].name + ": " + files[i].size + " bytes";
li.appendChild(info);
}
fileList.appendChild(list);
}
}
上传用户选择的文件
function sendFiles() {
var imgs = document.querySelectorAll(".obj");
for (var i = 0; i < imgs.length; i++) {
//一个IMG元素,一个File对象或Blob对象.
new FileUpload(imgs[i], imgs[i].file);
}
}
function FileUpload(img, file) {
var reader = new FileReader();
this.ctrl = createThrobber(img);
var xhr = new XMLHttpRequest();
this.xhr = xhr;
var self = this;
this.xhr.upload.addEventListener("progress", function(e) {
if (e.lengthComputable) {
var percentage = Math.round((e.loaded * 100) / e.total);
self.ctrl.update(percentage);
}
}, false);
xhr.upload.addEventListener("load", function(e){
self.ctrl.update(100);
var canvas = self.ctrl.ctx.canvas;
canvas.parentNode.removeChild(canvas);
}, false);
xhr.open("POST", "http://demos.hacks.mozilla.org/paul/demos/resources/webservices/devnull.php");
xhr.overrideMimeType('text/plain; charset=x-user-defined-binary');
reader.onload = function(evt) {
xhr.sendAsBinary(evt.target.result);
};
reader.readAsBinaryString(file);
}
异步实现文件上传
<?php
if (isset($_FILES['myFile'])) {
// Example:
move_uploaded_file($_FILES['myFile']['tmp_name'], "uploads/" . $_FILES['myFile']['name']);
exit;
}
?><!DOCTYPE html>
<html>
<head>
<title>dnd binary upload</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript">
function sendFile(file) {
var uri = "/index.php";
var xhr = new XMLHttpRequest();
var fd = new FormData();
xhr.open("POST", uri, true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
// Handle response.
alert(xhr.responseText); // handle response.
}
};
fd.append('myFile', file);
// Initiate a multipart/form-data upload
xhr.send(fd);
}
window.onload = function() {
var dropzone = document.getElementById("dropzone");
dropzone.ondragover = dropzone.ondragenter = function(event) {
event.stopPropagation();
event.preventDefault();
}
dropzone.ondrop = function(event) {
event.stopPropagation();
event.preventDefault();
var filesArray = event.dataTransfer.files;
for (var i=0; i<filesArray.length; i++) {
sendFile(filesArray[i]);
}
}
</script>
</head>
<body>
<div>
<div id="dropzone" style="margin:30px; width:500px; height:300px; border:1px dotted grey;">Drag & drop your file here...</div>
</div>
</body>
</html>
参考:
https://developer.mozilla.org/zh-CN/docs/Using_files_from_web_applicat…