js实现文件夹目录选择文件
使用 input 元素实现文件选择
在 HTML 中可以通过 input 元素实现文件选择功能。设置 type="file" 属性可以让用户选择文件,添加 webkitdirectory 和 directory 属性可以启用文件夹选择模式。
<input type="file" id="folderInput" webkitdirectory directory multiple>
JavaScript 部分可以监听 change 事件获取选择的文件列表:
document.getElementById('folderInput').addEventListener('change', function(event) {
const files = event.target.files;
for (let i = 0; i < files.length; i++) {
console.log(files[i].webkitRelativePath);
}
});
处理文件列表和路径
通过 webkitRelativePath 属性可以获取文件在文件夹中的相对路径。这个属性返回一个字符串,表示文件相对于所选文件夹的路径。

function handleFolderSelect(event) {
const files = Array.from(event.target.files);
const folderStructure = {};
files.forEach(file => {
const pathParts = file.webkitRelativePath.split('/');
let currentLevel = folderStructure;
for (let i = 0; i < pathParts.length - 1; i++) {
const part = pathParts[i];
if (!currentLevel[part]) {
currentLevel[part] = {};
}
currentLevel = currentLevel[part];
}
currentLevel[pathParts[pathParts.length - 1]] = file;
});
console.log(folderStructure);
}
使用拖放 API 实现文件夹选择
除了传统的文件选择对话框,还可以通过拖放 API 实现文件夹选择功能。需要阻止默认的拖放行为并处理 drop 事件。
const dropArea = document.getElementById('dropArea');
dropArea.addEventListener('dragover', (e) => {
e.preventDefault();
dropArea.classList.add('dragover');
});
dropArea.addEventListener('dragleave', () => {
dropArea.classList.remove('dragover');
});
dropArea.addEventListener('drop', (e) => {
e.preventDefault();
dropArea.classList.remove('dragover');
const items = e.dataTransfer.items;
const files = [];
for (let i = 0; i < items.length; i++) {
const entry = items[i].webkitGetAsEntry();
if (entry) {
traverseFileTree(entry, files);
}
}
console.log(files);
});
function traverseFileTree(entry, files, path = '') {
if (entry.isFile) {
entry.file(file => {
file.filepath = path + file.name;
files.push(file);
});
} else if (entry.isDirectory) {
const dirReader = entry.createReader();
dirReader.readEntries(entries => {
for (let i = 0; i < entries.length; i++) {
traverseFileTree(entries[i], files, path + entry.name + '/');
}
});
}
}
浏览器兼容性注意事项
文件夹选择功能在不同浏览器中的支持程度不同。webkitdirectory 属性主要在基于 WebKit 的浏览器中有效,如 Chrome 和 Edge。Firefox 从版本 50 开始支持 webkitdirectory,但行为可能略有不同。

function checkFolderSelectionSupport() {
const input = document.createElement('input');
input.type = 'file';
return 'webkitdirectory' in input || 'directory' in input;
}
if (!checkFolderSelectionSupport()) {
alert('您的浏览器不支持文件夹选择功能');
}
样式和用户体验优化
为文件选择控件添加适当的样式可以改善用户体验。可以使用 CSS 隐藏默认的输入控件,创建一个更美观的替代按钮。
.folder-input-wrapper {
position: relative;
overflow: hidden;
display: inline-block;
}
.folder-input-button {
padding: 8px 16px;
background: #4285f4;
color: white;
border-radius: 4px;
cursor: pointer;
}
#folderInput {
position: absolute;
left: 0;
top: 0;
opacity: 0;
width: 100%;
height: 100%;
cursor: pointer;
}
HTML 结构:
<div class="folder-input-wrapper">
<button class="folder-input-button">选择文件夹</button>
<input type="file" id="folderInput" webkitdirectory directory multiple>
</div>
处理大型文件夹
当用户选择包含大量文件的文件夹时,可能需要优化性能以避免界面冻结。可以使用 Web Workers 或分批处理文件。
async function processLargeFolder(files, batchSize = 100) {
for (let i = 0; i < files.length; i += batchSize) {
const batch = Array.from(files).slice(i, i + batchSize);
await processFileBatch(batch);
updateProgress(i + batch.length, files.length);
}
}
function processFileBatch(batch) {
return new Promise(resolve => {
setTimeout(() => {
batch.forEach(file => {
// 处理每个文件
});
resolve();
}, 0);
});
}
function updateProgress(processed, total) {
const percent = Math.round((processed / total) * 100);
console.log(`处理进度: ${percent}%`);
}






