Try   HackMD

【前端小抄】原生JS讀取、寫出檔案

tags: 小抄 JavaScript

運用FileFileListFileReader三個Web API,我們可以透過網頁上的元素獲取使用者選取的檔案。

<input>標籤獲得檔案

假設現在有這個很陽春的網頁:

<!DOCTYPE html>
<html>
<body>
    <input id = "input" accept = ".xml" type = "file">讀我</input>
    <p id = "result"></p>
</body>
</html>

因為使用者選取的檔案會被「儲存」在<input>元素中,所以我們要用FileList API存取這些檔案:

const Input = document.getElementById('input'); // 選取id為input的HTML標籤
const File = Input.files[0]; // 使用者選取的第一個檔案

接著為了讓JavaScript真正「拆開」檔案,我們須借助FileReader API之力:

function readFile(file) {
    
    const fileHandler = new FileReader(); // 建構一個名叫fileHandler的FileReader物件
    fileHandler.onload = (e) => {         // 當檔案讀取完成時(即Load事件發生時)執行

        document.getElementById('result').innerHTML = fileHandler.result;
                                          // 顯示檔案
    }
    
    fileHandler.readAsText(file,'utf-8'); // 將檔案以UTF-8編碼開啟
    
}

readFile(File);                           // 讀取剛接收的檔案

由Drop事件獲得檔案

Drop事件以及它的兄弟姊妹(Drag、DragEnd、DragEnter、DragLeave、DragOver、DragStart)可以由HTML Drag and Drop APIDataTransfer API存取,因此我們把網頁改成這樣:

<!DOCTYPE html>
<html>
<body>
    <div id = "input" ondrop = "readDroppedFile(event);">丟進來</div>
    <p id = "result"></p>
</body>
</html>

首先,我們需要先阻止瀏覽器嘗試開啟檔案(你現在可以嘗試拖曳PDF文件到瀏覽器中,瀏覽器預設會將其開啟),所以要加上這段程式碼:

function readDroppedFile(e) {
    
    e.preventDefault();    // 防止檔案被瀏覽器開啟
    
}

接著運用DataTransfer API,將程式改寫成這樣:

function readDroppedFile(e) {
    
    e.preventDefault();            // 防止檔案被瀏覽器開啟
    const dt = e.dataTransfer();     // 建構一個名叫dt的dataTransfer物件
    const File = dt.files[0];      // 使用者選取的第一個檔案
    readfile(File);                // 檔案已經可以餵給前面寫的readFile函數了!
    
}

完整小抄

<input>元素獲得檔案:

function readFile(file) { const Input = document.getElementById('input'); const File = Input.files[0]; const fileHandler = new FileReader(); fileHandler.onload = (e) => { return fileHandler.result; } fileHandler.readAsText(file,'utf-8'); } readFile(File);

由Drop事件獲得檔案:

function readDroppedFile(e) { e.preventDefault(); const dt = e.dataTransfer(); const File = dt.files[0]; const fileHandler = new FileReader(); fileHandler.onload = (e) => { return fileHandler.result; } fileHandler.readAsText(file,'utf-8'); } readDroppedFile(event);

其他補充