关键api:showDirectoryPicker,用户选择目录,返回值是一个句柄。
句柄的属性kind:file文件,directory文件夹。
句柄的属性name:文件/文件夹名称。
句柄的属性方法entries():返回目录下的文件和文件夹。
- 按钮打开文件夹选择器
const btn = document.getElementById('btn')
const contentBoxEle = document.getElementById('contentBox')
btn.onclick = async function(){
const handle = await showDirectoryPicker() // 打开文件夹选择器(异步操作)
await processHandle(handle) // 处理选择的文件夹(因为里面有读取文件的I/O操作,所以是异步)
const menuBoxEle = document.getElementById('menuBox') // 获取内容容器
createDirectoryMenu(handle, menuBoxEle) // 渲染目录内容
}
- 递归处理文件夹目录,生成通过children属性串联的树形结构
async function processHandle(handle){
if(handle.kind === 'file'){
return // 文件不处理
}else{
handle.children = []
const iter = await handle.entries()
for await (const entry of iter){
const subHandler = entry[1]
handle.children.push(subHandler)
await processHandle(subHandler)
}
}
}
- 递归渲染文件夹目录结构(这一步可以在上一步同时处理,不用再次递归,但本意是学习造轮子的过程,过程略)
<div class="container">
<div id="menuBox"></div>
<div id="contentBox"></div>
</div>
function createDirectoryMenu(data, root){
const detailsEle = document.createElement('details')
const summaryEle = document.createElement('summary')
const spanEle = document.createElement('span')
spanEle.innerText = data.name
summaryEle.appendChild(spanEle)
summaryEle.onclick = async function(){
if(data.kind === 'directory') return
const file = await data.getFile()
const reader = new FileReader()
reader.onload = function(e){
contentBoxEle.innerText = e.target.result
hljs.highlightAll()
}
reader.readAsText(file)
}
detailsEle.appendChild(summaryEle)
data.children?.forEach(item => {
createDirectoryMenu(item, detailsEle)
});
root.appendChild(detailsEle)
}
- 效果


1366

被折叠的 条评论
为什么被折叠?



