基於HTML5的移動Web應用——檔案操作
過去Web程式不能替代桌面程式的一個重要原因就在於瀏覽器對於檔案操作API的缺失。照片處理中的裁剪、濾鏡,二維碼的讀取與識別,檔案的檢視和編輯等,這些操作無一不依賴檔案的操作,HTML5賦予了瀏覽器幾乎和本地程式同等強大的檔案操作能力。
File API是HTML5在DOM標準中新增的功能,它允許Web內容在使用者授權的情況下選擇本地檔案並讀取內容一透過 File,FileList 和FileReader等物件共同作用來實現。
選擇檔案
1、透過表單選擇檔案
由於Web環境的特殊性,為了考慮檔案安全問題,瀏覽器不允許JavaScript直接訪問檔案系統,但可以透過file型別的input元素或者拖放的方式選擇檔案操作。
<input type="file" id="thisFile"/>
File表單可以讓使用者選取一個或者多個檔案(multiple 屬性),透過FileAPI,可在使用者選擇檔案後訪問到代表了所選檔案列表的FileList物件,FileList 物件是一個類陣列的物件,其中包含著一個或多個File物件。如果沒有multiple屬性或者使用者只選了一個檔案,那麼只需要訪問FileList物件的第一個元素:
var filelist=document.getElementById('thisFile') .files;
var selectedFile-filelist[0];
使用input元素時,使用者在選擇檔案後會觸發其change事件:
var inputElement=document.getElementById('thisFile')
inputElement. addEventListener ("change",handleFiles, false)
function handleFiles(){
var fileList=this.files
}
和其他類陣列物件一樣,FileList 也有length屬性,可以輕鬆遍歷其File物件:
for (var i=0, numFiles=files.length ; i< numFiles; i++) {
var file=files[i]
……
}
File物件有3個很有用的屬性,包括了關於該檔案的許多有用資訊。
(1) name: 檔名,不包含路徑資訊。
(2) size: 檔案大小,以B為單位。
(3) type:檔案的MIME type。
需要注意的是,這3個屬性都是隻讀的。
2、透過拖曳來選擇檔案
使用拖曳的方式來選擇檔案的效果,需要透過訪問dataTransfer的files屬性來實現。
下面透過一個案例來演示具體效果,如示例所示。
【示例】 使用拖曳的方式選擇檔案
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<style>
.dropzone{
width: 200px;
height: 100px;
border: 2px dashed #ddd;
text-align: center;
padding-top: 100px;
color: #999;
}
</style>
<body>
<div id="dropzone">
拖曳檔案到此處
</div>
<div id="output">
</div>
<script>
function getFileInfo(file) {
var aMultiples = ["KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"], sizeinfo;
var info = '檔名:' + file.name ;
// 計算檔案大小的近似值
for (var nMultiple = 0, nApprox = file.size / 1024; nApprox > 1; nApprox /= 1024, nMultiple++) {
sizeinfo = nApprox.toFixed(3) + " " + aMultiples[nMultiple] + " (" + file.size + " bytes)";
}
info += ";大小:" + sizeinfo
info += ";型別:" + file.type
return info + '<br>'
}
var dropzone = document.getElementById('dropzone');
dropzone.addEventListener('drop', function (e) {
var html = '您一共選擇了 ' + e.dataTransfer.files.length + '個檔案,檔案資訊如下:<br>';
[].forEach.call(e.dataTransfer.files, function (file) {
html += getFileInfo(file);
});
document.getElementById('output').innerHTML = html
e.preventDefault();
e.stopPropagation();
}, false);
dropzone.addEventListener('dragover', function (e) {
if (e.preventDefault) {
// 必須要阻止dragover的預設行為(即不可drop),這樣才能進行drop操作。
// 否則不會觸發drop事件
e.preventDefault();
}
return false
}, false)
</script>
</body>
</html>
用Chrome瀏覽器訪問示例。
操作檔案
1、FileReader 物件
前面講到表單或者dataTansier物件中的File型別的例項代表著這個檔案,但是這個檔案物件只能訪問到一些基本的資訊(大小和檔名等),如果要訪問檔案的具體內容,還得藉助FileReader物件。
FileReader物件可以將檔案物件轉換為字串、DataURL物件或者二進位制字串等,以進行進一步操作。例如,在做圖片上傳功能時,可以先對選擇的圖片進行預覽或者剪裁,待使用者確認無誤後再進行上傳,可以節省許多不必要的頻寬。以前文的拖曳檔案例子為基礎,加上拖曳圖片預覽功能,程式碼如示例所示。
【示例】 FileReader物件
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<style>
.dropzone {
width: 200px;
height: 100px;
border: 2px dashed #ddd;
text-align: center;
padding-top: 100px;
color: #999;
}
.preview img {
width: 100px;
height: 100px;
}
</style>
<body>
<div id="dropzone">
拖拽檔案到此處
</div>
<div id="preview">
</div>
<script>
function handleFiles(files) {
var preview = document.getElementById('preview')
for (var i = 0; i < files.length; i++) {
var file = files[i]
// 用來過濾非圖片型別
var imageType = /image.*/
if (!file.type.match(imageType)) {
continue
}
// 只能動態建立img物件來進行預覽
var img = document.createElement("img")
// 將檔案物件存起來
img.file = file
// 新建 FileRead 物件——是不是很簡單?
var reader = new FileReader()
// FileReader在讀取檔案時是非同步執行的(JS中許多物件都有類似API),因此需
要透過繫結其load事件來訪問檔案讀取的結果
// 要注意,這裡使用了閉包,因為img只儲存當前函式(handleFiles)內的引用,
for迴圈並不會建立新的作用域
// 因此要透過一個閉包的形式複製一份img的引用,否則img在for迴圈結束後將
只引用最後一次建立的img元素。
reader.{
return function(e) {
// e.target.result 包含讀取到的 dataURL資訊
aImg.src = e.target.result
// 將圖片插入當前檔案
preview.appendChild(aImg)
}
})(img)
reader.(e) {
console.log('當前已載入:' + (e.loaded / e.total * 100).toFixed(2)
+ '%')
}
// readAsDataURL方法將file物件讀取為dataURL
reader.readAsDataURL(file)
}
}
var dropzone = document.getElementById('dropzone')
dropzone.addEventListener('drop', function (e) {
handleFiles(e.dataTransfer.files)
e.preventDefault()
e.stopPropagation()
}, false)
dropzone.addEventListener('dragover', function (e) {
if (e.preventDefault) {
e.preventDefault()
}
return false
}, false)
</script>
</body>
</html>
用瀏覽器訪問該頁面。
從上面的例子可以看到FileReader()的基本用法。readAsDataURL()方法用於讀取檔案,它接收一個File 或者Blob物件的例項作為引數,並將檔案內容轉換為一個base64編碼的URL字串,並透過load事件將結果傳遞到e.target.result上。FileReader物件除了readAsDataURL()方法外,還有其他幾個方法用於讀取檔案內容的操作。
(1) readAsArrayBuffer(Blob|File): 讀取檔案,最後result屬性將包含ArrayBuffer物件以表示檔案內容。ArrayBuffer 物件用來表示固定長度二進位制資料的緩衝區。
(2) readAsBinaryString(Blob|File):讀取檔案, result屬性包含檔案的原始二進位制資料。每個位元組均由一個[0.255]範圍內的整數表示。
(3) readAsText(BloblFile,encoding): 以文字方式讀入檔案,並可以指定返回資料的編碼,預設為UTF-8。
(4) abort): 終止正在進行的讀取操作。如果FileReader 物件沒有進行讀取操作,呼叫此方法會丟擲DOM_FILE_ABORT_ERR異常。
2、Blob 物件
以上讀取檔案操作的方法有兩個共同點,一是都接受一個 Blob或File型別的物件。
var fileParts=['<a>hey man</a>'];
var myB1ob=new B1ob (fileParts,{ "type":"text/xml"});
Blob物件還支援slice() 方法,用於對資料進行切割:
var yourBlob = myB1ob.slice (10,20) ;
File物件同樣繼承了Blob的slice()方法,可以利用此方法對File物件預先進行分割,然後再讀取、上傳,最後在伺服器端進行組裝——非同步上傳的原理就是這樣。如果再記住分割點,這樣即使網路中途斷掉,也可以在下次傳輸時從斷點續傳。
除了都接受Blob和File物件,這些方法另外一個共同點是,由於JavaScript本身基於事件驅動,這些和平臺相關的方法都是非同步方法。即呼叫時立即返回,讀取檔案操作完成後再觸發相應的load事件。
除了load事件,FileReader 物件還會呼叫這樣一些事件處理程式。
(1) onabort:當讀取操作被終止時呼叫(呼叫abort 方法)
(2) onerror: 當讀取操作傳送錯誤時呼叫。
(3) onload: 當讀取操作成功完成時呼叫。
(4) onloadend:當讀取操作完成時呼叫,不管是成功還是失敗,該處理程式在onload或者onerror後呼叫。
(5) onloadstart: 當讀取操作將要開始之前呼叫。
(6) onprogress:在讀取資料過程中週期性呼叫。該事件為最有用的事件,在載入較大的檔案時,可以提供一個進度條讓使用者知道當前載入進度,不讓使用者產生焦躁感。
reader.{
console.log('當前檔案已載入'+ e.loaded/e. total*100.toFixed(2)+'%')
}
e.total儲存著當前檔案的總大小(位元組),e.loaded 表示當前檔案已經載入了多少。
要想將圖片檔案轉換成可以直接在HTML裡引用的URL,除了前文提到的readAsDataURL()方法,還可以使用window.URL .createObjectURL()方法:
var objectURL =window.URL. crea teObjectURL (file0bj) ;
objectURL最後會得到一個類似blob: null/a672ae4c- f84e- 45d2- -87ae-f45dc986d601的字串,這個字串可以直接被IMG等元素引用。
objectURL和dataURL一樣可以直接被img的src屬性引用,就像Windows平臺下的檔案控制程式碼或者Linux下的檔案描述符,在使用完之後通常還要呼叫window.URL.revokeObjectURL()方法進行釋放,如果不顯示呼叫該方法,objectURL 將會在檔案解除安裝時自動釋放。對於前文的例子可以簡單修改為URL物件版本:
function handleFiles (files) {
var preview=document.getElementById('preview')
for(var i=0;i<files.length;i++) {
var file=files [i]
……
var img=document.createElement("img")
img.src=window. URL.createObjectURL(file)
img.{
window.URL.revoke0bjectURL(this.src)
}
Preview. appendChild (img)
}
}
有了操作檔案的利器,讀者可以做一些有趣的功能,比如實現類似Photoshop中圖片處理的濾鏡或者讀取PDF檔案並轉換為HTML格式等
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69940641/viewspace-2942210/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 基於HTML5的移動Web應用HTMLWeb
- 基於HTML5的移動Web應用——Geolocation地理定位HTMLWeb
- 基於Docker應用容器日誌檔案收集Docker
- 基於 HTML5 Canvas 的拓撲元件 ToolTip 應用HTMLCanvas元件
- 基於 HTML5 的電力接線圖 SCADA 應用HTML
- 基於vue全家桶的移動端音樂web appVueWebAPP
- 移動檔案
- 1.4檔案操作之修改程式配置檔案小應用
- Dore 混合應用框架 —— 基於 React Native 的混合應用遷移方案框架React Native
- 輕鬆玩轉Python檔案操作:移動、刪除Python
- 基於vue-cli配置移動端rem自適應專案VueREM
- 基於 HTML5 WebGL 的 3D 風機 Web 組態工業網際網路應用HTMLWeb3D
- 輕鬆搭建基於 SpringBoot + Vue 的 Web 商城應用Spring BootVueWeb
- “易+”開源 | 基於 ijkplayer 的 LLS-Player 移動端應用實踐
- 基於豆瓣api的快應用專案API
- 相容移動端的 Web 檔案館視覺化管理系統Web視覺化
- 基於 HTML5 的計量站三維視覺化監控系統 Web 組態工控應用HTML視覺化Web
- Web 和移動應用程式測試之間的區別Web
- Python基礎——檔案操作Python
- 用 Visual Studio Code 做基於 .NET MAUI 跨平臺移動應用開發UI
- 輕鬆搭建基於 Serverless 的 Egg.js Web 應用ServerJSWeb
- 12_基於 AspectJ 配置檔案實現 AOP 操作
- 12C關於CDB、PDB線上移動資料檔案、線上重新命名資料檔案的操作說明
- 基於 HTML5 WebGL 的計量站三維視覺化監控系統 Web 組態工控應用HTMLWeb視覺化
- 基於 Canvas 的 HTML5 文字動畫特效CanvasHTML動畫特效
- 基於 HTML5 WebGL 的挖掘機 3D 視覺化應用HTMLWeb3D視覺化
- 《Flask Web開發 基於Python的Web應用開發實戰》簡評FlaskWebPython
- [譯] Dweb: 基於 IPFS 的去中心化 Web 檔案系統 (中英)Web中心化
- python——批次移動檔案Python
- Spring Boot Web應用程式下載Excel檔案 - simplesolutionSpring BootWebExcel
- 關於移動端OCR證件識別的應用
- python 檔案操作的基礎總結Python
- day07.檔案操作/綜合應用【Python教程】Python
- 如何應用於Web框架的搭建Web框架
- 關於 Web 應用的 Prerender 策略Web
- Dart 2 Web 應用遷移指南DartWeb
- 基於 WebGL 3D 的 HTML5檔案館視覺化管理系統Web3DHTML視覺化
- 基於 HTML5 的 WebGL 3D 檔案館視覺化管理系統HTMLWeb3D視覺化