1. File API簡介
File API對于某些專門的網站的不可或缺的。現在常用它實現對文件的預覽等功能。
File API規定怎么從硬盤上提取文件,直接交給在網頁中運行中的Javascript代碼。然后代碼可以打開文件探究數據,無論是本地文件還是其他文件。注意,關鍵在于文件會被直接交給JavaScript代碼,它并不能修改文件,也不能創建新文件,想要保存任何數據,需要將數據發送到服務器或者保存在本地存儲空間中。
2. 讀取文件
在通過File API操作文件之前,首先必須取得文件。使用File API可以直接讀取文本文件的內容。
例如:
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><title>文件上傳</title><style>#fileOutput {border:1px grey solid;width: 500px;}</style>
</head>
<body><input type="file" id="fileInput" onChange="processFiles(this.files)"><div id="fileOutput"></div>
<script>function processFiles(files) {//每個文件對象都有三個有用的屬性:name屬性保存文件名,size屬性保存文件的字節大小,type保存文件的MEMI類型var file = files[0];//創建FileReader對象,var reader = new FileReader();//FileReader用來提取文件內容,但是這個方法是異步的,要提取文件,首先要處理onLoad事件reader.onload = function(e) {//這個事件發生了,意味著數據準備好了,//把它復制到頁面的div元素中var output = document.getElementById("fileOutput");//將文件內容轉換成一個長字符串,保存在onload事件的e.target.result中output.textContent = e.target.result;};//調用FileReader的readAsText()方法reader.readAsText(file);}
</script>
</body>
</html>
上圖中,選擇一個文件,無需上傳,網頁中的javascript代碼就能取得文本文件,把內容復制到頁面中。
readAsText()方法只能處理文本內容的文件,如CSV格式,XML格式,.docx格式和.xlsx格式的文件。
readAsText()方法只是眾多讀取文件的方法之一,還有readAsBinaryStrng(),readAsDataURL()和readAsArrayBuffer().
- readAsBinaryStrng()方法可以讓應用處理二進制編碼的數據,但基本上就是把數據保存在一個文本字符串中,效率不高。
- readAsArrayBuffer()是對于做數據處理較好的選擇,這個方法將數據讀到一個數組中,每個數組項代表一字節數據。這套方案的優勢是可以用來創建大塊數據,然后切分成更小的二進制數據塊,以便逐塊處理。
- readAsDataURL()方法則讓我們能方便地取到圖片數據。
2.1 一次讀取多個文件
HTML5也支持一次提交多個文件,只要為<input>
元素添加multiple屬性即可:
<input type="file" id="Files" name="files[]" multiple />
<div id="Lists"></div>
function fileSelect(e) { e = e || window.event; var files = e.target.files; //FileList Objects var output = []; for(var i = 0, f; f = files[i]; i++) { output.push('<li><strong>' + f.name + '</strong>(' + f.type + ') - ' + f.size +' bytes</li>'); } document.getElementById('Lists').innerHTML = '<ul>' + output.join('') + '</ul>'; } if(window.File && window.FileList && window.FileReader && window.Blob) { document.getElementById('Files').addEventListener('change', fileSelect, false);
} else { document.write('您的瀏覽器不支持File Api');
}
由以上代碼可以看到,html5為file這個dom元素新增了files接口(e.target指向了file input元素,實際上也可以用this來訪問,即this.files),得到的就是FileList,通過遍歷該集合,即可訪問到各個已選擇的文件對象。
2.2 通過拖拽讀取圖片文件
前面我們看到,FileReader處理文本內容只需要一步,同樣,處理圖片內容也這么簡單,而這就要歸功于readAsDataURL()方法。
下面的例子中,讓用戶把圖片拖到頁面中,然后在圖片上繪制。
下面是HTML和css代碼
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>拖拽圖片</title><style>#dropBox {margin: 15px;width: 300px;height: 300px;border:5px dashed grey;border-radius: 8px;background: lightyellow;background-size: 100%;background-repeat: no-repeat;text-align: center;}#dropBox div{margin: 100px 70px;color: orange;font-size: 25px;}</style>
</head><body><div id="dropBox"><div>將你的圖片拖到此處</div></div>
</body>
</html>
為處理放置文件的操作,需要處理三個事件:onDragEnter、onDragOver、onDrop。頁面一加載完成,就會為這三個事件添加處理程序。
var dropBox;
window.onload = function() {dropBox = document.getElementById("dropBox");dropBox.ondragenter = ignoreDrag;dropBox.ondragover = ignoreDrag;dropBox.ondrop = drop;
}
其中,ignoreDrag()函數同時處理onDragEnter和onDragOver事件,前者在鼠標指針進入放置區時發生,后者在拖動文件的鼠標指針位于放置區之上時發生。之所以用同一個函數處理兩個事件,原因就是不必對這兩個事件作出反應,只要告訴瀏覽器自己什么也不做即可。
function ignoreDrag(e) {
//因為我們在處理拖放,所以應該確保沒有其他元素會取得這個事件e.stopPropagation();e.preventDefault();
}
我們要響應的事件是onDrop,這個事件一發生就說明要取得和處理文件了。
function drop(e) {//取消事件傳播及默認行為e.stopPropagation();e.preventDefault();//取得拖進來的文件var data = e.dataTransfer;var files = data.files;//將其傳給真正的處理文件的函數processFiles(files);
}function processFiles(files) {var file = files[0];//創建FileReadervar reader = new FileReader();//告訴它準備好數據URL之后做什么reader.onload = function(e) {dropBox.style.backgroundImage = "url('" + e.target.result + "')";};//讀取圖片:將圖片轉化為數據URLreader.readAsDataURL(file);
}
效果圖:
拖拽前:
拖拽后:
2.3 瀏覽器對File API的支持情況
更多內容請參考此處