翻譯自MDN
使用HTML5中添加到DOM的File API,web內(nèi)容現(xiàn)在可以要求用戶選擇本地文件竖幔,然后讀取這些文件的內(nèi)容∈峭担可以通過使用HTML <input>元素或拖放操作來完成此選擇拳氢。
訪問本地文件
html語法:
<input type="file" id="input">
File API可以從 File
對象中讀取FlieList,FlieList中包含了用戶所選取的文件
如果用戶只選取了一個文件,那么我們只需要考慮第一個文件對象
使用DOM讀取選擇的文件:
var selectedFile = document.getElementById('input').files[0];
通過一個change
事件訪問選擇的文件
可以通過change
事件(不強制)訪問FlieList,
<input type="file" id="input" onchange="handleFiles(this.files)">
當(dāng)用戶選擇一個文件時,handleFiles()
函數(shù)將調(diào)用一個FlieList對象蛋铆,該對象包含表示用戶選擇的文件的文件對象馋评。
如果您想讓用戶選擇多個文件,只需使用輸入元素上的multiple
屬性:
<input type="file" id="input" multiple onchange="handleFiles(this.files)">
在這種情況下刺啦,傳遞給handleFiles()
函數(shù)的文件列表包含用戶所選擇的每個文件的一個文件對象留特。
獲取選中文件的信息
DOM提供的FlieList對象列出由用戶選擇的所有文件,每個文件都指定為一個File
對象。通過檢查文件列表長度屬性的值蜕青,您可以確定用戶選擇了多少個文件:
var numFiles = files.length;
單個文件對象可以通過簡單地訪問列表數(shù)組來檢索:
for (var i = 0, numFiles = files.length; i < numFiles; i++) {
var file = files[i];
..
}
這個循環(huán)遍歷文件列表中的所有文件苟蹈。
File
對象有三個帶有文件信息的屬性
- name 文件名(只讀),不包含文件路徑信息
- size 文件大小(只讀),單位是字節(jié)(bytes)
- type 文件的MIME-type,如果獲取不到文件的MIME-type,則這個屬性就是一個空字符串
示例:顯示文件的大小
下面的示例顯示了可能使用的大小屬性
<!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";
// optional code for multiples approximation
for (var aMultiples = ["KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"], nMultiple = 0, nApprox = nBytes / 1024; 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>
使用click()方法使用隱藏的文件輸入元素
從 Gecko 2.0 (Firefox 4 / Thunderbird 3.3 / SeaMonkey 2.1)開始,您可以隱藏公認的丑陋文件<input>
元素,并呈現(xiàn)您自己的接口右核,以打開并顯示用戶選擇的文件慧脱。您可以通過將input
元素設(shè)計為display:none
并調(diào)用< input >
元素的click()
方法。
<input type="file" id="fileElem" multiple accept="image/*" style="display:none" onchange="handleFiles(this.files)">
<a href="#" id="fileSelect">Select some files</a>
處理單擊事件的代碼可以如下所示:
var fileSelect = document.getElementById("fileSelect"),
fileElem = document.getElementById("fileElem");
fileSelect.addEventListener("click", function (e) {
if (fileElem) {
fileElem.click();
}
e.preventDefault(); // prevent navigation to "#"
}, false);
您可以按您希望的那樣贺喝,樣式化新的按鈕來打開文件選擇器菱鸥。
使用label元素觸發(fā)隱藏的文件輸入元素
<input type="file" id="fileElem" multiple accept="image/*" style="display:none" onchange="handleFiles(this.files)">
<label for="fileElem">Select some files</label>
沒有必要添加JavaScript代碼來調(diào)用文件元素的click()
。在這種情況下躏鱼,您可以按照您的希望來樣式化標(biāo)簽元素氮采。
使用拖放來選取文件
您還可以讓用戶將文件拖放到web應(yīng)用程序中。
首先是設(shè)置一個接收的區(qū)域染苛。根據(jù)你的應(yīng)用程序的設(shè)計鹊漠,你的內(nèi)容的不同部分會接受不同的內(nèi)容,但是讓元素接收drop事件是很容易的:
var dropbox;
dropbox = document.getElementById("dropbox");
dropbox.addEventListener("dragenter", dragenter, false); //進入
dropbox.addEventListener("dragover", dragover, false);//移動
dropbox.addEventListener("drop", drop, false);//放下
在本例中,我們將帶ID dropbox
的元素轉(zhuǎn)換為我們的drop區(qū)域殖侵。這是通過監(jiān)聽dragente
r、dragover
和drop
事件來實現(xiàn)的镰烧。
在我們的例子中拢军,我們實際上不需要對dragenter
和dragover
事件做任何事情,所以這些函數(shù)都很簡單怔鳖。他們只是停止傳播事件茉唉,防止發(fā)生默認的行為:
function dragenter(e) {
e.stopPropagation();
e.preventDefault();
}
function dragover(e) {
e.stopPropagation();
e.preventDefault();
}
真正的魔法發(fā)生在drop()函數(shù)中:
function drop(e) {
e.stopPropagation();
e.preventDefault();
var dt = e.dataTransfer;
var files = dt.files;
handleFiles(files);
}
這里,我們從事件中檢索dataTransfer
字段结执,將文件列表拉出度陆,然后將其傳遞給handleFiles()
。從這一點來看献幔,處理文件的方式與用戶使用輸入元素或拖放的方式是一樣的懂傀。
顯示圖片的縮略圖
假設(shè)您正在開發(fā)下一個偉大的照片共享網(wǎng)站,并希望使用HTML5在用戶實際上傳圖片之前顯示縮略圖預(yù)覽蜡感。您可以像前面討論的那樣建立您的輸入元素或刪除區(qū)域蹬蚁,并將其調(diào)用為以下函數(shù),如handlefile()
函數(shù)郑兴。
function handleFiles(files) {
for (var i = 0; i < files.length; i++) {
var file = files[i];
var imageType = /^image\//;
if (!imageType.test(file.type)) {
continue;
}
var img = document.createElement("img");
img.classList.add("obj");
img.file = file;
preview.appendChild(img); // Assuming that "preview" is the div output where the content will be displayed.
var reader = new FileReader();
reader.onload = (function(aImg) { return function(e) { aImg.src = e.target.result; }; })(img);
reader.readAsDataURL(file);
}
}
在這里犀斋,我們的循環(huán)處理用戶選擇的文件,查看每個文件的類型屬性情连,看它是否是一個圖像文件(通過在MIME類型字符串模式“image / *”上進行正則表達式匹配)叽粹。對于每個圖像文件,我們創(chuàng)建一個新的img元素。
給每個img對象添加一個file屬性以辨認 File;這將讓我們稍后獲取實際上傳的圖像虫几。使用Node.appendChild()
將新縮略圖添加到文檔的預(yù)覽區(qū)域锤灿。
接下來,新建一個FileReader對象來處理異步加載圖像并將其附加到img元素持钉。創(chuàng)建了新的FileReader對象后衡招,設(shè)置onload
函數(shù),然后調(diào)用readAsDataURL()
以在后臺啟動讀操作每强。當(dāng)加載圖像文件的全部內(nèi)容時始腾,它們將轉(zhuǎn)換為數(shù)據(jù)傳遞給onload回調(diào)的URL。這個示例的實現(xiàn)將img元素的src屬性設(shè)置為加載的圖像空执,結(jié)果顯示在用戶屏幕上的縮略圖中出現(xiàn)的圖像浪箭。
使用 object URLs
Gecko 2.0 (Firefox 4 / Thunderbird 3.3 / SeaMonkey 2.1) 支持DOM 的 window.URL.createObjectURL()
和window.URL.revokeObjectURL()
方法.這些可以創(chuàng)建簡單的URL字符串,可以用來引用任何可以引用DOM File
對象的數(shù)據(jù),包括用戶計算機上的本地文件
當(dāng)您有一個文件對象時辨绊,您希望從HTML中引用URL奶栖,您可以為它創(chuàng)建一個object URL:
var objectURL = window.URL.createObjectURL(fileObj);
object URL是標(biāo)識文件對象的字符串。每次調(diào)用window.URL.createObjectURL()
時门坷,都會創(chuàng)建一個唯一的object URL,即使之前已經(jīng)給這個文件創(chuàng)建過一個對象了宣鄙。當(dāng)文檔被卸載時,它們會自動被釋放默蚌,如果你的頁面動態(tài)地使用它們冻晤,你應(yīng)該通過調(diào)用window.URL.revokeObjectURL()
顯式地釋放它們
window.URL.revokeObjectURL(objectURL);