1、前端小练习(一)-------- 实现网页端的文件资源管理器

JS实现资源管理器功能介绍:


内容目录:

  • 效果图
  • 界面介绍
  • 实现原理
  • 总结

网页效果图


image

界面介绍


整个页面比较简单,主要有两个部分组成,

分别是:左边显示文件夹层级目录、右边显示文件内容的显示区域。

实现原理


技术:html+CSS+JS(+JQuery)

组件: 图标样式库 css文件;
解析markdown文件


根据上面的页面介绍我们将页面大致分为两个部分:文件夹层级显示区域、文件内容显示区域

直接上代码:







资源管理器

















因为个人原因给初始页面只是加载两个小按钮,需要点击按钮后进行扩展,下面我直接贴上CSS代码

*{
margin: 0;
padding: 0;
}

body{
position: fixed;
width: 100%;
height: 100%;
background: url("../image/background/personage.jpg")no-repeat;
background-size: cover;
}

/开始整体框架进行搭建/

/首先是左边的资源管理器界面端/
/这边进行做一个动画效果/
#showFolder{
width:50px;
height: 50px;
border-radius: 10px;
background: rgba(0,0,0,.3);
color: white;
user-select: none;
transition: width 1s,height 1s;
overflow: hidden;
}
/左边上面的标题部分/
#showFolder #showTitle{
width: 100%;
height:50px;
display: flex;
font-size: 20px;
align-items: center;
overflow: hidden;
}

showTitle:hover{

cursor: pointer;
}

showFolder .titleText{

width: calc(100% - 50px);
display: none;
}
/下面的层级目录的显示修饰部分/
#showFolder .folderMenu{
margin-top: 10px;
width: 100%;
height: calc(100% - 60px);
transition: height 1s;
text-align: center;
display: none;
overflow-y: visible;
overflow-x:hidden ;
}

/打开文件按钮的修饰/
#showFolder .folderMenu Button{
border-radius: 3px;
border-style: none;
text-align: center;
padding: 3px;
width: 98%;
background: #4158D0;
color: white;
}

/* 下面我们需要对文件资源管理器进行修饰管理 */
.folderMenu .folder,.folderMenu .file{
width: 230px;
height: 28px;
display: flex;
align-items: center;
overflow: hidden;
font-size: 14px;
}

.folderMenu .folder:hover,
.folderMenu .file:hover{
cursor: pointer;
color:#FFE4C4;
}
.folderMenu .file .fileName{
text-align: left;
white-space: nowrap;
overflow: hidden;
}

.folderMenu .childen_Area{
margin-left: 20px;
overflow: hidden;
}
/右边文件内容显示区域/
#showTxt{
color: white;
font-size: 20px;
position: fixed;
top: 0;
right: 0;
width: 50px;
height: 50px;
border-radius: 20px;
background: rgba(0,0,170,.3);
transition: height 1s,width 1s;
}
/右边文件内容显示区域中标题栏/
#showTxt .showTxt_Title{
position: fixed;
top: 0px;
right: 0px;
user-select: none;
width: 50px;
height: 50px;
text-align: center;
line-height: 50px;
}
/文件内容显示区域中主体部分/
#showTxt .showTxt_Content{
margin: 60px 10px 5px 30px;
width: calc(100% - 40px);
height: calc(100% - 65px);
overflow-y: auto;
font-family: "华文宋体";
}

JS部分,主要讲一下主要实现思路:

1、首先是用户点击按钮,触发事件。
2、然后JS通过异步调用 window.showDirectoryPicker()函数,获得到选中的文件夹的句柄(handle)
3、创建一个异步函数进行处理这个句柄 (我自己命名)processHandle(handle, Elem),分别有两个参数,分别是需要传递的句柄,需要向某个元素添加内容(也就是需要显示在哪块区域中)。
4、在processHandle(handle, Elem)中我们需要做的事情有下面两个:
~ 通过entires()函数,获取一个异步迭代器
~ 然后就需要遍历这个迭代器(这个时候我们获取的是我们选择的文件夹中子文件以及子文件夹),通过判断迭代器中每个元素中kind属性,进行判断该元素是文件(同时创建文件图标以及显示文件名)还是文件夹(同样的创建下拉图标、文件夹图标以及显示文件夹名字);
5、创建文件图标的函数creatElem_File(root,Elem) :root是当前文件夹句柄,Elem是当前文件夹所对应的document的元素

  • 首先创建外面的div进行包裹着整个边框
  • 创建 用来显示文件图标
  • 创建一个div显示文件名字
  • 然后将2和3添加到1中
  • 最后将1添加到参数Elem中
  • 创建对应的点击事件(点击事件是load线程中,而之前访问夹是异步线程)

6、创建文件夹图标的函数 creatElem_Folder(root,Elem):root是当前文件夹句柄,Elem是当前文件夹所对应的document的元素

  • 首先创建外面的div进行包裹着整个边框
  • 创建 用来显示下拉图标
  • 创建 用来显示文件夹图标
  • 创建一个div显示文件名字
  • 需要将2和3添加到1中
  • 然后将1添加到参数Elem中
  • 我们需要再次调用processHandle(handle, Elem)函数,形成递归过程,达到遍历每一个文件夹的目的
  • 创建对应的点击事件(点击事件是load线程中,而之前访问夹是异步线程)

下面就是展示JS代码:

window.onload=async () => {
// fa-bar图标的点击事件
$("#showTitle").click(showTitle_Click);

// 打开文件夹的点击事件
$("#openFolder").click(await openFolder_Click);

// 点击expand图标后显示文本区域
$("#showTxt .showTxt_Title .fa").click(expandICON_Click);
}

// 区域动画展示效果函数
function showTitle_Click() {
/* 主要是做一个动画效果 */
const showFolder=$("#showFolder")[0];
const titleText= $(".titleText")[0];
const folderMenu=$("#showFolder .folderMenu")[0];
if(showFolder.clientWidth==50){
showFolder.style.width="200px";
showFolder.style.height="100%";

setTimeout(()=>{titleText.style.display="block";
folderMenu.style.display="block";
folderMenu.style.height="calc(100% - 60px)";
},800);
}else{
// 返回到原来的样式
showFolder.style.width="50px";
showFolder.style.height="50px";
titleText.style.display="none";
folderMenu.style.height="0px";
}

}

/**
* 打开文件夹按钮响应事件
* @returns {Promise}
*/
async function openFolder_Click(){
try{
const handle=await window.showDirectoryPicker();
const folderMenu=$(".folderMenu")[0];
$("#openFolder")[0].style.display="none";
// 然后将handle交给专门的函数进行处理
await processHandle(handle,folderMenu);
}catch (e){
console.log(e)
}
}

/**
* 处理获取本地文件的句柄,运用递归的方式进行遍历旗下所有的子文件以及子目录
* @param handle
* @param Elem
* @returns {Promise}
*/
async function processHandle(handle, Elem) {
const iter = handle.entries();
for await (const item of iter) {
if (item[1].kind == "file") {
creatElem_File(item[1], Elem);
} else {
creatElem_Folder(item[1], Elem);
}
}
return;
}

function creatElem_File(root,Elem) {
// 首先是创建外面包裹的标签
let facting_File=document.createElement("div");
facting_File.className="file";
facting_File.style.marginLeft="10px";
/*
1、文件图标包括:图标+文件名
2、创建每一个文件点击响应事件
*/
// 创建文件夹图标节点
let file_ICON=document.createElement("i");
file_ICON.className="file_ICON fa fa-file";
let file_Name=document.createElement("div");
file_Name.className="fileName";
file_Name.style.marginLeft="5px";
file_Name.prepend(root.name);
facting_File.appendChild(file_ICON);
facting_File.appendChild(file_Name);
Elem.appendChild(facting_File);

// 创建每个文件的对应的点击事件
facting_File.onclick=()=>{
// 从支线线程转到加载线程 此时调用异步线程中对象会包裹成promise对象
const showTxt=$("#showTxt")[0];
const showTxt_Content=$("#showTxt .showTxt_Content")[0]
if(showTxt.clientWidth<=60){
// 首先调用文本区域的显示函数
expandICON_Click();
}
let promise=root.getFile();
// 这边读取时是需要进行分类解析的
/* 首先是创建几个正则表达式,用来检测是否是对应的文件
*/

const reg=/(.csv|.txt)$/m
const reg1=/(.md)$/m;
const reg2=/(.jp[e]g|.png)$/m;

const reader=new FileReader();
promise.then(result=>{
// 然后进入promise对象处理异步线程中进行分门别类进行读取文件
if(reg.test(result.name)){
console.log("读取文件");
reader.readAsText(result,"utf-8");
reader.onload=(evt)=>{
showTxt_Content.innerHTML=evt.target.result;
}
}
if(reg1.test(result.name)){
console.log("读取markdown文件");
reader.readAsText(result,"utf-8");
reader.onload=(evt)=>{
showTxt_Content.innerHTML=marked.parse(evt.target.result);
}
}

if(reg2.test(result.name)){
console.log("读取二进制文件")
reader.readAsDataURL(result);
reader.onload=(evt)=>{
showTxt_Content.innerHTML="";
let image=document.createElement("img");
image.style.width="95%";
image.style.height="80%";
image.style.margin=" 0 auto";
image.src=evt.target.result;
console.log(evt.target.result);
showTxt_Content.appendChild(image);
}
}
});
}
}

function creatElem_Folder(root,Elem){
/*
1、创建文件夹层级包含:箭头、文件夹图标、文件名
2、创建子级隐藏的区域,并且调用process函数进行遍历文件夹层级
*/
// 这是创建外面包裹的边框
let facting_Folder=document.createElement("div");
facting_Folder.className="folder";
// 创建下拉箭头
let xiala=document.createElement("i");
xiala.className="xiala fa fa-circle-chevron-right"
xiala.style.marginLeft="5px";
// 创建文件夹图标
let folder_ICON=document.createElement("i");
folder_ICON.className="folder_ICON fa fa-folder-closed";
folder_ICON.style.marginLeft="5px";
// 创建文件夹名字显示区域
let folder_Name=document.createElement("div");
folder_Name.append(root.name);
folder_Name.style.marginLeft="5px";

facting_Folder.appendChild(xiala);
facting_Folder.appendChild(folder_ICON);
facting_Folder.appendChild(folder_Name);
Elem.appendChild(facting_Folder);
// 然后我们需要创建专门的区域来显示子层级目录
let childen_Area=document.createElement("div");
childen_Area.className="childen_Area";
childen_Area.style.display="none";
Elem.appendChild(childen_Area);
processHandle(root,childen_Area);

// 我们还需要创建对应文件夹打开响应事件
facting_Folder.onclick=()=>{
if(childen_Area.style.display=="none"){
// 首先是将下拉图标的方向进行更换
xiala.className="xiala fa fa-circle-chevron-down";
folder_ICON.className="folder_ICON fa fa-folder-open";
// 然后将这个子层级显示出来
childen_Area.style.display="block";
}else{
xiala.className="xiala fa fa-circle-chevron-right";
folder_ICON.className="folder_ICON fa fa-folder-closed";
// 然后将这个子层级显示出来
childen_Area.style.display="none";
}
}
}

// 显示文本区域动画过度效果
function expandICON_Click() {
const showTxt=$("#showTxt")[0];
if(showTxt.clientWidth<=70){
showTxt.style.width="calc(100% - 200px)";
showTxt.style.height ="100%";
}else{
showTxt.style.width="50px";
showTxt.style.height ="50px";
}
}

总结


主要自己从想出概念,到找到思路然后确定思路(中间花费很多时间),然后到代码落地碰到很多困难。也是幸运地能够实现自己想出来的概念。我自己是从CSDN、博客园以及抖音中无意中看到推荐视频,刚好看到该知识点的视频,解决我自己碰到的问题,幸运儿。

posted @ 2023-03-20 17:10  什么都会有的  阅读(1232)  评论(0)    收藏  举报