你能够在chrome扩展等代码中使用DOM File API ;事实上有些须要注意的额外特性。参考 Using the DOM File API in chrome code 。php
访问选中的文件Edit
考虑下面的HTML:css
<input type="file" id="input">
使用HTML5 DOM新增的File API,如今可让网页要求用户选择本地文件,而且读取这些文件的信息了。选择的方式既能够是HTML<input>
元素,也能够是拖拽 。javascript
你能够在chrome扩展等代码中使用DOM File API ;事实上有些须要注意的额外特性。参考 Using the DOM File API in chrome code 。php
考虑下面的HTML:css
<input type="file" id="input">
经过File API,咱们能够在用户选取一个或者多个文件以后,访问到表明了所选文件的一个或多个File
对象,这些对象被包含在一个FileList
对象中.html
若是用户只选择了一个文件,那么咱们只须要访问这个FileList
对象中的第一个元素.java
可使用传统的DOM选择方法来获取到用户所选择的文件:jquery
var selected_file = document.getElementById('input').files[0];
还可使用jQuery选择器来选择:web
var selectedfile = $('#input').get(0).files[0]; var selectedFile = $('#input')[0].files[0];
若是你有一个"files is undefined
" 错误,那么就是你没有选择正确的HTML元素,忘记了一个jQuery选择器返回的是匹配的DOM元素的列表。用获取的DOM元素调用“files”的方法就能够了。正则表达式
另外,还能够在input
元素上的change
事件触发时再访问它的FileList
属性(但不是强制性的):chrome
<input type="file" id="input" onchange="handleFiles(this.files)">
当用户成功选取若干个文件后,handleFiles()
函数会被调用,且一个表明用户所选择的文件的包含了File
对象的FileList
对象会做为参数传入该函数。canvas
若是你的程序可让用户选择多个文件,记得要在input元素上加上
multiple
属性:
<input type="file" id="input" multiple onchange="handleFiles(this.files)">
在用户选择了多个文件的状况下,传入handleFiles()
函数的文件列表将会包含多个File
对象,每一个File
对象对应一个真实的文件。
你还能够经过element.addEventListener()
方法来添加多个change
事件处理函数,像这样:
var inputElement = document.getElementById("inputField"); inputElement.addEventListener("change", handleFiles, false); function handleFiles() { var fileList = this.files; }
用户所选择的文件都存储在了一个FileList
对象上,其中每一个文件都对应了一个File
对象。你能够经过这个FileList
对象的length
属性知道用户一共选择了多少个文件:
var numFiles = files.length;
能够经过普通的循环语句来操做每一个单独的File
对象:
for (var i = 0, numFiles = files.length; i < numFiles; i++) { var file = files[i]; .. }
File
对象上有三个属性提供了所包含文件的相关信息.
name
size
type
下面的例子演示了size
属性的用法:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>File(s) size</title> <script> function updateSize() { var nBytes = 0, oFiles = document.getElementById("uploadInput").files, nFiles = oFiles.length; for (var nFileId = 0; nFileId < nFiles; nFileId++) { nBytes += oFiles[nFileId].size; } var sOutput = nBytes + " bytes"; var aMultiples = ["KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"], nMultiple = 0, nApprox = nBytes / 1024; // optional code for multiples approximation for ( ; nApprox > 1; nApprox /= 1024, nMultiple++) { sOutput = nApprox.toFixed(3) + " " + aMultiples[nMultiple] + " (" + nBytes + " bytes)"; } // end of optional code document.getElementById("fileNum").innerHTML = nFiles; document.getElementById("fileSize").innerHTML = sOutput; } </script> </head> <body onload="updateSize();"> <form name="uploadForm"> <p> <input id="uploadInput" type="file" name="myFiles" onchange="updateSize();" multiple> selected files: <span id="fileNum">0</span>; total size: <span id="fileSize">0</span> </p> <p> <input type="submit" value="Send file"> </p> </form> </body> </html>
从Gecko 2.0 (Firefox 4 / Thunderbird 3.3 / SeaMonkey 2.1)开始,你能够隐藏掉默认的的
文件输入框<input>
元素,使用自定义的界面来充当打开文件选择对话框的按钮.实现起来很简单,你只须要使用样式display:none把本来的
文件输入框隐藏掉,而后在须要的时候调用它的click()
方法就好了.
考虑一下下面的HTML:
<input type="file" id="fileElem" multiple accept="image/*" style="display:none" onchange="handleFiles(this.files)"> <a href="#" id="fileSelect">Select some files</a>
为自定义的按钮绑定click
事件:
var fileSelect = document.getElementById("fileSelect"), fileElem = document.getElementById("fileElem"); fileSelect.addEventListener("click", function (e) { if (fileElem) { fileElem.click(); } e.preventDefault(); // prevent navigation to "#" }, false);
这样,你就能任意改变这个新按钮的样式了.
你可让用户将本地文件拖放到你的应用程序上.
首先要建立一个拖放操做的目的区域:
第一步是创建一个放置区域。可根据您的应用程序的设计来决定哪部分的内容接受 drop,但建立一个接收drop事件的元素是简单的:
var dropbox; dropbox = document.getElementById("dropbox"); dropbox.addEventListener("dragenter", dragenter, false); dropbox.addEventListener("dragover", dragover, false); dropbox.addEventListener("drop", drop, false);
在这个例子中,ID为dropbox
的元素所在的区域是咱们的拖放目的区域。咱们须要在该元素上绑定dragenter,
dragover,
和drop事件。
咱们必须阻止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; handleFiles(files); }
在该函数中,咱们从事件对象中获取到dataTransfer
对象,把该对象包含的Filelist
对象传入函数handleFiles(),
这个函数会无区别的对待从input元素或拖放操做中来的文件
列表。
假设你正在开发下一个伟大的照片分享网站,并但愿使用HTML5在用户上传他们图片以前进行缩略图预览。您能够如前面所讨论的创建一个输入元素或者拖放区域,并调用一个函数,以下面的handleFiles()函数。
function handleFiles(files) { for (var i = 0; i < files.length; i++) { var file = files[i]; var imageType = /^image\//; if ( ) { continue; } var img = document.createElement("img"); img.classList.add("obj"); img.file = file; preview.appendChild(img); var reader = new FileReader(); reader.onload = (function(aImg) { return function(e) { aImg.src = e.target.result; }; })(img); reader.readAsDataURL(file); } }!imageType.test(file.type)// Assuming that "preview" is the div output where the content will be displayed
这里咱们循环处理用户选择的文件,查看每一个文件的类型属性,看看这是不是一个图像文件(经过一个正则表达式匹配字符串“image.*”)。对于每 个图片文件,咱们建立一个新的img元素。CSS能够用于创建任何漂亮的边界,阴影,和指定图像的大小,因此,甚至不须要在这里完成。
每张图片咱们添加一个obj类,让他们更容易的在DOM树中被找到。咱们也在图片上添加了一个file属性来确认每张图片的 File
,这样能够帮助咱们在以后真正的上传工做时获取到图片。最后咱们使用 Node.appendChild()
把缩略图添加到咱们先前的文档区域中。
而后,咱们创建了{ { domxref(FileReader)} }来处理图片的异步加载,并把它添加到img元素上。在建立新的FileReader对象以后,咱们创建了onload函数,而后调用 readAsDataURL()开始在后台进行读取操做。当图像文件的全部内容加载后,他们转换成一个 data: URL,传递到onload回调函数中。以后只须要把img元素的src属性设置为这个加载过的图像,就可让图像的缩略图出如今用户的屏幕 上。
Gecko 2.0 (Firefox 4 / Thunderbird 3.3 / SeaMonkey 2.1)开始支持window.URL.createObjectURL()
和 window.URL.revokeObjectURL()
两个DOM方法。这两个方法建立简单的URL字符串对象,用于指向任何 DOM File
对象数据,包括用户电脑中的本地文件。
当你想要在HTML中经过URL来引用File
对象,你能够参考以下方式建立:
var objectURL = window.URL.createObjectURL(fileObj);
URL对象是 File
对象的一个字符串标识。 每次调用window.URL.createObjectURL()
的时候,会建立一个惟一的URL对象,即便你已经为该文件建立了URL对象。这些对象都必须被释放。 当文档被卸载时,它们会自动释放,若是你的页面动态地使用它们,你应该明确地经过调用window.URL.revokeObjectURL()
释放它们:
window.URL.revokeObjectURL(objectURL);
这个例子使用了对象URL来显示图片缩略图,同时还显示了图片的其余信息,包括图片名和图片大小,你能够查看该例子的在线演示.
负责界面呈现的HTML以下:
<input type="file" id="fileElem" multiple accept="image/*" style="display:none" onchange="handleFiles(this.files)"> <a href="#" id="fileSelect">Select some files</a> <div id="fileList"> <p>No files selected!</p> </div>
这创建文件的<input>
元素就像一个调用文件选择器的连接(由于咱们要隐藏文件输入,以防止表现出不友好的UI)。这部分将在 Using hidden file input elements using the click() method里解释,由于是调用文件选择器的方法。
下面是 handleFiles()方法
:
window.URL = window.URL || window.webkitURL; var fileSelect = document.getElementById("fileSelect"), fileElem = document.getElementById("fileElem"), fileList = document.getElementById("fileList"); fileSelect.addEventListener("click", function (e) { if (fileElem) { fileElem.click(); } e.preventDefault(); // prevent navigation to "#" }, false); 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); } }
This starts by fetching the URL of the <div>
with the ID fileList
. This is the block into which we'll insert out file list, including thumbmails.
If the FileList
object passed to handleFiles()
is null
, we simply set the inner HTML of the block to display "No files selected!". Otherwise, we start building our file list, as follows:
<ul>
) element is created.<div>
block by calling its element.appendChild()
method.File
in the FileList
represented by files
:
<li>
) element and insert it into the list.<img>
) element.window.URL.createObjectURL()
to create the blob URL.window.URL.revokeObjectURL()
method, passing in the object URL string as specified by img.src
.你能够异步的将用户所选择的文件上传到服务器上(好比一张图片).
Continuing with the code that builds the thumbnails in the previous example, recall that every thumbnail image is in the CSS class obj
, with the corresponding File
attached in a file
attribute. This lets us very easily select all the images the user has chosen for uploading using Document.querySelectorAll()
, like this:
function sendFiles() { var imgs = document.querySelectorAll(".obj"); for (var i = 0; i < imgs.length; i++) { new FileUpload(imgs[i], imgs[i].file); } }
Line 2 creates an array, called imgs
, of all the elements in the document with the CSS class obj
. In our case, these will be all the image thumbnails. Once we have that list, it's trivial to go through the list, creating a new FileUpload
instance for each. Each of these handles uploading the corresponding file.
FileUpload
函数接受两个参数:一个IMG
元素,一个File
对象或Blob
对象.
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); }
The FileUpload()
function shown above creates a throbber, which is used to display progress information, then creates an XMLHttpRequest
to handle uploading the data.
Before actually transferring the data, several preparatory steps are taken:
XMLHttpRequest
's upload progress
listener is set to update the throbber with new percentage information, so that as the upload progresses, the throbber will be updated based on the latest information.XMLHttpRequest
's upload load
event handler is set to update the throbber with 100% as the progress information (to ensure the progress indicator actually reaches 100%, in case of granularity quirks during the process). It then removes the throbber, since it's no longer needed. This causes the throbber to disappear once the upload is complete.XMLHttpRequest
's open()
method to start generating a POST request.XMLHttpRequest
function overrideMimeType()
. In this case, we're using a generic MIME type; you may or may not need to set the MIME type at all, depending on your use case.FileReader
object is used to convert the file to a binary string.XMLHttpRequest
function sendAsBinary()
is called to upload the file's content.<?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>
URLs对象不只仅是可用于图像!它们可用于显示嵌入的PDF文件,或能够由浏览器显示的任何其它资源。
在火狐中,使PDF出如今内嵌的iframe中(并不建议做为一个下载的文件),把偏好pdfjs.disabled设置为false 。
<iframe id="viewer">
src
属性在这里有些变化:
var obj_url = window.URL.createObjectURL(blob); var iframe = document.getElementById('viewer'); iframe.setAttribute('src', obj_url); window.URL.revokeObjectURL(obj_url);
你能够用一样的方式操纵其它格式的文件。下面是如何预览上传的视频:
var video = document.getElementById('video'); var obj_url = window.URL.createObjectURL(blob); video.src = obj_url; video.play() window.URL.revokeObjectURL(obj_url);