欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

前端如何實現對本地文件的IO操作詳解

 更新時間:2024年07月17日 09:28:26   作者:接著奏樂接著舞。  
這篇文章主要給大家介紹了關于前端如何實現對本地文件IO操作的相關資料,需要的朋友可以參考下

前言

在網頁中,前端已經可以讀取本地文件系統(tǒng),對本地的文件進行IO讀寫,甚至可以制作一個簡單的VScode編輯器。這篇文章以漸進式方式實現此功能,文末附上所有代碼。

首先看整體功能演示

功能概述

我們將實現一個簡單的 Web 應用,具備以下功能:

  • 選擇本地目錄:用戶可以選擇本地目錄并顯示其結構。
  • 文件瀏覽:用戶可以瀏覽目錄中的文件和子目錄。
  • 文件編輯:用戶可以選擇文件并在網頁上進行編輯。
  • 文件保存:用戶可以將編輯后的文件保存到本地。

核心實現步驟

我們將功能拆分為以下幾個核心步驟:

  • 選擇本地目錄
  • 構建文件樹
  • 讀取和編輯文件
  • 保存編輯后的文件

1. 選擇本地目錄

選擇本地目錄是實現這個功能的第一步。我們使用 File System Access API 的 showDirectoryPicker 方法來選擇目錄。

document.getElementById('selectDirectoryButton').addEventListener('click', async function() {
    try {
        const directoryHandle = await window.showDirectoryPicker();
        console.log(directoryHandle);  // 打印目錄句柄
    } catch (error) {
        console.error('Error: ', error);
    }
});

2. 構建文件樹

選擇目錄后,我們需要遞歸地構建文件樹,并在頁面上顯示文件和子目錄。

async function buildFileTree(directoryHandle, parentElement) {
    for await (const [name, entryHandle] of directoryHandle.entries()) {
        const li = document.createElement('li');
        li.textContent = name;

        if (entryHandle.kind === 'file') {
            li.classList.add('file');
            li.addEventListener('click', async function() {
                currentFileHandle = entryHandle;
                const file = await entryHandle.getFile();
                const fileContent = await file.text();
                document.getElementById('fileContent').textContent = fileContent;
                document.getElementById('editArea').value = fileContent;
                document.getElementById('editArea').style.display = 'block';
                document.getElementById('saveButton').style.display = 'block';
            });
        } else if (entryHandle.kind === 'directory') {
            li.classList.add('folder');
            const ul = document.createElement('ul');
            ul.style.display = 'none';
            li.appendChild(ul);
            li.addEventListener('click', function() {
                ul.style.display = ul.style.display === 'none' ? 'block' : 'none';
            });
            await buildFileTree(entryHandle, ul);
        }
        parentElement.appendChild(li);
    }
}

3. 讀取和編輯文件

當用戶點擊文件時,我們讀取文件內容,并在文本區(qū)域中顯示以便編輯。

li.addEventListener('click', async function() {
    currentFileHandle = entryHandle;
    const file = await entryHandle.getFile();
    const fileContent = await file.text();
    document.getElementById('fileContent').textContent = fileContent;
    document.getElementById('editArea').value = fileContent;
    document.getElementById('editArea').style.display = 'block';
    document.getElementById('saveButton').style.display = 'block';
});

4. 保存編輯后的文件

編輯完成后,用戶可以點擊保存按鈕將修改后的文件內容保存回本地文件。

document.getElementById('saveButton').addEventListener('click', async function() {
    if (currentFileHandle) {
        const editArea = document.getElementById('editArea');
        const updatedContent = editArea.value;

        // 創(chuàng)建一個 writable 流并寫入編輯后的文件內容
        const writable = await currentFileHandle.createWritable();
        await writable.write(updatedContent);
        await writable.close();

        // 更新顯示區(qū)域的內容
        document.getElementById('fileContent').textContent = updatedContent;
    }
});

核心 API 介紹

window.showDirectoryPicker()

該方法打開目錄選擇對話框,并返回一個 FileSystemDirectoryHandle 對象,代表用戶選擇的目錄。

const directoryHandle = await window.showDirectoryPicker();

FileSystemDirectoryHandle.entries()

該方法返回一個異步迭代器,用于遍歷目錄中的所有文件和子目錄。

for await (const [name, entryHandle] of directoryHandle.entries()) {
    // 處理每個文件或目錄
}

FileSystemFileHandle.getFile()

該方法返回一個 File 對象,表示文件的內容。

const file = await fileHandle.getFile();

FileSystemFileHandle.createWritable()

該方法創(chuàng)建一個可寫流,用于寫入文件內容。

const writable = await fileHandle.createWritable();
await writable.write(content);
await writable.close();

總結

通過以上步驟,我們能夠選擇本地目錄、瀏覽文件和子目錄、讀取和編輯文件內容,并將編輯后的文件保存回本地。同時,我們使用 Highlight.js 實現了代碼高亮顯示。

源碼

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Local File Browser with Edit and Save</title>
    <link rel="stylesheet"  rel="external nofollow" >
    <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.4.0/highlight.min.js"></script>
    <style>
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            margin: 0;
            padding: 0;
            display: flex;
            height: 100vh;
            overflow: hidden;
            background-color: #2e2e2e;
            color: #f1f1f1;
        }
        #sidebar {
            width: 20%;
            background-color: #333;
            border-right: 1px solid #444;
            padding: 20px;
            box-sizing: border-box;
            overflow-y: auto;
        }
        #content {
            width: 40%;
            padding: 20px;
            box-sizing: border-box;
            overflow-y: auto;
        }
        #preview {
            width: 40%;
            padding: 20px;
            box-sizing: border-box;
            overflow-y: auto;
            background-color: #1e1e1e;
            border-left: 1px solid #444;
        }
        #fileTree {
            list-style-type: none;
            padding: 0;
        }
        #fileTree li {
            margin-bottom: 5px;
            cursor: pointer;
            user-select: none; /* 禁止文本選中 */
        }
        #fileTree .folder::before {
            content: "??";
            margin-right: 5px;
        }
        #fileTree .file::before {
            content: "??";
            margin-right: 5px;
        }
        #fileContent {
            white-space: pre-wrap; /* Preserve whitespace */
            background-color: #1e1e1e;
            padding: 10px;
            border: 1px solid #444;
            min-height: 200px;
            color: #f1f1f1;
        }
        #editArea {
            width: 100%;
            height: calc(100% - 40px);
            background-color: #1e1e1e;
            color: #f1f1f1;
            border: 1px solid #444;
            padding: 10px;
            box-sizing: border-box;
        }
        #saveButton {
            margin-top: 10px;
            background-color: #4caf50;
            color: white;
            border: none;
            padding: 10px 15px;
            cursor: pointer;
            border-radius: 5px;
        }
        #saveButton:hover {
            background-color: #45a049;
        }
        h1 {
            font-size: 1.2em;
            margin-bottom: 10px;
        }
        ::-webkit-scrollbar {
            width: 8px;
        }
        ::-webkit-scrollbar-track {
            background: #333;
        }
        ::-webkit-scrollbar-thumb {
            background-color: #555;
            border-radius: 10px;
            border: 2px solid #333;
        }
        .hidden {
            display: none;
        }
    </style>
</head>
<body>
    <div id="sidebar">
        <h1>選擇目錄</h1>
        <button id="selectDirectoryButton">選擇目錄</button>
        <ul id="fileTree"></ul>
    </div>
    <div id="content">
        <h1>編輯文件</h1>
        <textarea id="editArea"></textarea>
        <button id="saveButton">保存編輯后的文件內容</button>
    </div>
    <div id="preview">
        <h1>本地文件修改后的實時預覽</h1>
        <pre><code id="fileContent" class="plaintext"></code></pre>
    </div>

    <script>
        let currentFileHandle = null;

        document.getElementById('selectDirectoryButton').addEventListener('click', async function() {
            try {
                const directoryHandle = await window.showDirectoryPicker();
                const fileTree = document.getElementById('fileTree');
                fileTree.innerHTML = ''; // 清空文件樹

                async function buildFileTree(directoryHandle, parentElement) {
                    for await (const [name, entryHandle] of directoryHandle.entries()) {
                        const li = document.createElement('li');
                        li.textContent = name;

                        if (entryHandle.kind === 'file') {
                            li.classList.add('file');
                            li.addEventListener('click', async function() {
                                currentFileHandle = entryHandle;
                                const file = await entryHandle.getFile();
                                const fileContent = await file.text();
                                const fileExtension = name.split('.').pop();

                                const codeElement = document.getElementById('fileContent');
                                const editArea = document.getElementById('editArea');
                                codeElement.textContent = fileContent;
                                editArea.value = fileContent;
                                codeElement.className = ''; // 清除之前的語言類
                                codeElement.classList.add(getHighlightLanguage(fileExtension));
                                hljs.highlightElement(codeElement);

                                // 顯示編輯區(qū)域和保存按鈕
                                editArea.style.display = 'block';
                                document.getElementById('saveButton').style.display = 'block';
                            });
                        } else if (entryHandle.kind === 'directory') {
                            li.classList.add('folder');
                            const ul = document.createElement('ul');
                            ul.classList.add('hidden'); // 默認隱藏子目錄
                            li.appendChild(ul);
                            li.addEventListener('click', function(event) {
                                event.stopPropagation(); // 阻止事件冒泡
                                ul.classList.toggle('hidden');
                            });
                            await buildFileTree(entryHandle, ul);
                        }
                        parentElement.appendChild(li);
                    }
                }

                await buildFileTree(directoryHandle, fileTree);
            } catch (error) {
                console.log('Error: ', error);
            }
        });

        // 獲取代碼高亮語言類型
        function getHighlightLanguage(extension) {
            switch (extension) {
                case 'js': return 'javascript';
                case 'html': return 'html';
                case 'css': return 'css';
                case 'json': return 'json';
                case 'xml': return 'xml';
                case 'py': return 'python';
                case 'java': return 'java';
                default: return 'plaintext';
            }
        }

        // 保存編輯后的文件內容
        document.getElementById('saveButton').addEventListener('click', async function() {
            if (currentFileHandle) {
                const editArea = document.getElementById('editArea');
                const updatedContent = editArea.value;

                // 創(chuàng)建一個 writable 流并寫入編輯后的文件內容
                const writable = await currentFileHandle.createWritable();
                await writable.write(updatedContent);
                await writable.close();

                // 更新高亮顯示區(qū)域的內容
                const codeElement = document.getElementById('fileContent');
                codeElement.textContent = updatedContent;
                hljs.highlightElement(codeElement);
            }
        });

        // 初始化 highlight.js
        hljs.initHighlightingOnLoad();
    </script>
</body>
</html>

到此這篇關于前端如何實現對本地文件的IO操作的文章就介紹到這了,更多相關前端本地文件的IO操作內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • BootstrapTable refresh 方法使用實例簡單介紹

    BootstrapTable refresh 方法使用實例簡單介紹

    本文就bootstrapTable refresh 方法如何傳遞參數做簡單舉例說明,非常不錯,具有參考借鑒價值,需要的朋友參考下吧
    2017-02-02
  • Javascript attachEvent傳遞參數的辦法

    Javascript attachEvent傳遞參數的辦法

    找了半天找到的解決辦法,看介紹說是javascript的閉包問題,導致得不能直接讀取外部的那個函數,不然就所有傳遞的參數都變?yōu)樽詈笠粋€了。
    2009-12-12
  • 最精簡的JavaScript實現鼠標拖動效果的方法

    最精簡的JavaScript實現鼠標拖動效果的方法

    這篇文章主要介紹了最精簡的JavaScript實現鼠標拖動效果的方法,可實現javascript控制鼠標拖動div層效果的方法,需要的朋友可以參考下
    2015-05-05
  • js導出table到excel同時兼容FF和IE示例

    js導出table到excel同時兼容FF和IE示例

    js導出table到excel,在百度可以搜索很多的方法,但是其兼容性是相當差的,本文制定了一個可以同時兼容FF和IE的方法,感興趣的朋友可以參考下
    2013-09-09
  • 使用JavaScript平移和縮放圖像的示例代碼

    使用JavaScript平移和縮放圖像的示例代碼

    平移和縮放是查看圖像時常用的功能,我們可以放大圖像以查看更多細節(jié),進行圖像編輯,Dynamsoft Document Viewer是一個用于此目的的SDK,它為文檔圖像提供了一組查看器,在本文中,我們將演示如何使用它來平移和縮放圖像,需要的朋友可以參考下
    2024-08-08
  • js 動態(tài)文字滾動的例子

    js 動態(tài)文字滾動的例子

    在文本框中動態(tài)滾動文字的例子,需要的朋友可以參考下。
    2011-01-01
  • JS實現可編輯的后臺管理菜單功能【附demo源碼下載】

    JS實現可編輯的后臺管理菜單功能【附demo源碼下載】

    這篇文章主要介紹了JS實現可編輯的后臺管理菜單功能,涉及javascript針對頁面元素的遍歷及動態(tài)修改相關操作技巧,并附帶demo源碼供讀者下載參考,需要的朋友可以參考下
    2016-09-09
  • 詳解js中構造流程圖的核心技術JsPlumb

    詳解js中構造流程圖的核心技術JsPlumb

    這篇文章主要介紹了js中構造流程圖的核心技術JsPlumb,jsPlumb是一個強大的JavaScript連線庫,它可以將html中的元素用箭頭、曲線、直線等連接起來,適用于開發(fā)Web上的圖表、建模工具等,需要的朋友可以參考下
    2015-12-12
  • 深入理解ES6之數據解構的用法

    深入理解ES6之數據解構的用法

    本文介紹了深入理解ES6之數據解構的用法,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-01-01
  • 簡單的無縫滾動程序-僅幾行代碼

    簡單的無縫滾動程序-僅幾行代碼

    簡單的無縫滾動程序-僅幾行代碼...
    2007-05-05

最新評論