詳解Js 根據(jù)文件夾目錄獲取Json數(shù)據(jù)輸出demo
1.搭建初始樣式(html,css)
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <style> h2 { text-align: center; } #file_input { display: none; } .userBtn { padding: 6px 25px; background: #00bfff; border-radius: 4px; color: white; cursor: pointer; border: none; } .userBtn:active { background-color: #00bfff90; } .userBtn[disabled] { background: #00bfff60; cursor: not-allowed; } #dataShowArea { width: 100%; height: 600px; border: 1px solid #000; box-sizing: border-box; margin-top: 20px; overflow: hidden; padding: 20px; padding-top: 10px; background: #0cff0014; border-radius: 6px; display: flex; flex-wrap: wrap; flex-direction: column; } #dataShowArea #realityArea { width: 100%; flex: 1; overflow: overlay; box-sizing: border-box; margin: 0px; color: #3300ed; /* border: 1px solid #3300ed; */ border-radius: 6px; } #dataShowArea #realityArea::-webkit-scrollbar { display: none; } #dataShowArea .hintUser{ width: 100%; color: #3300ed; text-align: center; font-style: italic; margin-bottom: 10px; } .userBtnArea{ width: 100%; display: flex; align-items: center; justify-content: space-around; } </style> </head> <body> <h2>文件夾路徑生成json文件</h2> <div class="userBtnArea"> <button id="coverInput" class="userBtn" onclick="coverInputClick()">選擇文件夾</button> <button id="saveJson" class="userBtn" onclick="saveJsonFile()" disabled>輸出JSON文件</button> </div> <!-- 選取單個(gè)文件夾 --> <input type="file" id="file_input" webkitdirectory directory onchange="outputFile(this.files)" /> <!-- 存放加載文件的數(shù)據(jù)的區(qū)域 --> <div id="dataShowArea"> <div class="hintUser">數(shù)據(jù)預(yù)覽</div> <pre id="realityArea" class="hljs"></pre> </div> <script> //全局的文件 json 數(shù)據(jù) let filesData = ''; let obj = document.getElementById('realityArea'); let saveJsonBtn = document.getElementById('saveJson'); </script> </body> </html>
2.文件夾目錄轉(zhuǎn)換成JSON數(shù)據(jù)
//File 文件格式需要轉(zhuǎn)成 Object => 將字段提出方便裝換 const fileField = [ 'lastModified', 'lastModifiedDate', 'name', 'size', 'type', 'webkitRelativePath', ]; //文件 目錄數(shù)據(jù)生成 async function handleFiles(files) { if (files.length > 0) { let catalogue = { // childer:{} }; for (fileItem of files) { //獲取要插入的對(duì)象 => File類型不能直接插入,會(huì)報(bào)錯(cuò) => File類型不歸屬于Object類型 let fileData = {}; fileField.forEach((item) => { fileData[item] = eval(`fileItem.${item}.toString()`); }); //文件的name值為 xx.文件屬性 會(huì)在執(zhí)行插入語(yǔ)句時(shí)報(bào)錯(cuò),只拿文件名,不拿文件屬性 fileData.noTypeName = fileData.name.split('.')[0]; let fileData_ = JSON.stringify(fileData); //獲取樹(shù)的每個(gè)字段 let catalogueField = fileItem.webkitRelativePath.split('/'); //要執(zhí)行的js語(yǔ)句拼接 let objStr = catalogueField.reduce((pre, cur, index, arr) => { /** * pre:上一次調(diào)用返回的值,或者提供的初始值 * cur:數(shù)組中當(dāng)前處理的元素 * index:數(shù)組中當(dāng)前處理的元素的下標(biāo) * arr:調(diào)用reduce函數(shù)的數(shù)組 * */ if (index >= arr.length - 1) { !eval(pre) && eval(`${pre}={isLeaf:true}`); pre = `${pre}['${fileData.noTypeName}']`; } else { index == 0 ? (pre = `${pre}['${cur}']`) : (pre = `${pre}.Folder['${cur}']`); !eval(pre) && eval(`${pre}={isLeaf:false,type:'folder',Folder:{}}`); } return pre; }, 'catalogue'); eval(`${objStr}={isLeaf:true,...${fileData_}}`); } return catalogue; } }
3.JSON數(shù)據(jù)輸出成JSON文件
//寫(xiě)成json文件輸出 function saveToJson(data) { if (!data) { console.error('json文件的數(shù)據(jù)對(duì)象不存在'); return; } var content = JSON.stringify(data, null, '\t'); // 轉(zhuǎn)成blob數(shù)據(jù)對(duì)象 var blob = new Blob([content], { type: 'text/plain;charset=utf-8', }); //第二步 => 文件數(shù)據(jù) 轉(zhuǎn)為可以 下載 的地址路徑 改路徑指向文件數(shù)據(jù) let url = window.URL.createObjectURL(blob); //動(dòng)態(tài)創(chuàng)建a標(biāo)簽 => 模擬觸發(fā)a標(biāo)簽的下載 => 用于將生成的json數(shù)據(jù)下載到本地 let link = document.createElement('a'); link.style.display = 'none'; link.href = url; link.setAttribute('download', 'model.json'); document.body.appendChild(link); link.click(); document.body.removeChild(link); //URL.createObjectURL函數(shù)創(chuàng)建的數(shù)據(jù)不會(huì)再內(nèi)存刪除 得手動(dòng)刪除或者瀏覽器轉(zhuǎn)態(tài)退出 window.URL.revokeObjectURL(url); }
4.完整代碼
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <style> h2 { text-align: center; } #file_input { display: none; } .userBtn { padding: 6px 25px; background: #00bfff; border-radius: 4px; color: white; cursor: pointer; border: none; } .userBtn:active { background-color: #00bfff90; } .userBtn[disabled] { background: #00bfff60; cursor: not-allowed; } #dataShowArea { width: 100%; height: 600px; border: 1px solid #000; box-sizing: border-box; margin-top: 20px; overflow: hidden; padding: 20px; padding-top: 10px; background: #0cff0014; border-radius: 6px; display: flex; flex-wrap: wrap; flex-direction: column; } #dataShowArea #realityArea { width: 100%; flex: 1; overflow: overlay; box-sizing: border-box; margin: 0px; color: #3300ed; /* border: 1px solid #3300ed; */ border-radius: 6px; } #dataShowArea #realityArea::-webkit-scrollbar { display: none; } #dataShowArea .hintUser{ width: 100%; color: #3300ed; text-align: center; font-style: italic; margin-bottom: 10px; } .userBtnArea{ width: 100%; display: flex; align-items: center; justify-content: space-around; } </style> </head> <body> <h2>文件夾路徑生成json文件</h2> <div class="userBtnArea"> <button id="coverInput" class="userBtn" onclick="coverInputClick()">選擇文件夾</button> <button id="saveJson" class="userBtn" onclick="saveJsonFile()" disabled>輸出JSON文件</button> </div> <!-- 選取單個(gè)文件 --> <!-- <input type="file" id="file" onchange="handleFiles(this.files)" /> --> <!-- 選取多個(gè)文件 --> <!-- <input type="file" id="file_input" multiple="multiple" onchange="handleFiles(this.files)" /> --> <!-- 選取單個(gè)文件夾 --> <input type="file" id="file_input" webkitdirectory directory onchange="outputFile(this.files)" /> <!-- 存放加載文件的數(shù)據(jù)的區(qū)域 --> <div id="dataShowArea"> <div class="hintUser">數(shù)據(jù)預(yù)覽</div> <pre id="realityArea" class="hljs"></pre> </div> <script> //全局的文件 json 數(shù)據(jù) let filesData = ''; let obj = document.getElementById('realityArea'); let saveJsonBtn = document.getElementById('saveJson'); //按鈕點(diǎn)擊觸發(fā)input標(biāo)簽的點(diǎn)擊 function coverInputClick() { document.getElementById('file_input').click(); } //報(bào)錯(cuò)json文件 function saveJsonFile(data) { saveToJson(filesData); } //File 文件格式需要轉(zhuǎn)成 Object => 將字段提出方便裝換 const fileField = [ 'lastModified', 'lastModifiedDate', 'name', 'size', 'type', 'webkitRelativePath', ]; //文件 目錄數(shù)據(jù)生成 async function handleFiles(files) { if (files.length > 0) { let catalogue = { // childer:{} }; for (fileItem of files) { //獲取要插入的對(duì)象 => File類型不能直接插入,會(huì)報(bào)錯(cuò) => File類型不歸屬于Object類型 let fileData = {}; fileField.forEach((item) => { fileData[item] = eval(`fileItem.${item}.toString()`); }); //文件的name值為 xx.文件屬性 會(huì)在執(zhí)行插入語(yǔ)句時(shí)報(bào)錯(cuò),只拿文件名,不拿文件屬性 fileData.noTypeName = fileData.name.split('.')[0]; let fileData_ = JSON.stringify(fileData); //獲取樹(shù)的每個(gè)字段 let catalogueField = fileItem.webkitRelativePath.split('/'); //要執(zhí)行的js語(yǔ)句拼接 let objStr = catalogueField.reduce((pre, cur, index, arr) => { /** * pre:上一次調(diào)用返回的值,或者提供的初始值 * cur:數(shù)組中當(dāng)前處理的元素 * index:數(shù)組中當(dāng)前處理的元素的下標(biāo) * arr:調(diào)用reduce函數(shù)的數(shù)組 * */ if (index >= arr.length - 1) { !eval(pre) && (eval(`${pre}={isLeaf:true}`)) pre = `${pre}['${fileData.noTypeName}']`; } else { index == 0 ? pre = `${pre}['${cur}']` : pre = `${pre}.Folder['${cur}']`; !eval(pre) && (eval(`${pre}={isLeaf:false,type:'folder',Folder:{}}`)) } // !eval(pre) && (eval(`${pre}={isLeaf:false}`)) return pre; }, 'catalogue'); eval(`${objStr}={isLeaf:true,...${fileData_}}`); }; return catalogue; } } //寫(xiě)成json文件輸出 function saveToJson(data) { if (!data) { console.error("json文件的數(shù)據(jù)對(duì)象不存在"); return; } /** * JSON.stringify(value[, replacer [, space]]) * * value:將要序列化成 一個(gè) JSON 字符串的值。 * * replacer * 如果該參數(shù)是一個(gè)函數(shù),則在序列化過(guò)程中,被序列化的值的每個(gè)屬性都會(huì)經(jīng)過(guò)該函數(shù)的轉(zhuǎn)換和處理; * 如果該參數(shù)是一個(gè)數(shù)組,則只有包含在這個(gè)數(shù)組中的屬性名才會(huì)被序列化到最終的 JSON 字符串中; * 如果該參數(shù)為 null 或者未提供,則對(duì)象所有的屬性都會(huì)被序列化。 * * space * 指定縮進(jìn)用的空白字符串,用于美化輸出(pretty-print); * 如果參數(shù)是個(gè)數(shù)字,它代表有多少的空格;上限為 10。該值若小于 1,則意味著沒(méi)有空格; * 如果該參數(shù)為字符串(當(dāng)字符串長(zhǎng)度超過(guò) 10 個(gè)字母,取其前 10 個(gè)字母),該字符串將被作為空格; * 如果該參數(shù)沒(méi)有提供(或者為 null),將沒(méi)有空格。 * */ var content = JSON.stringify(data, null, '\t'); // 轉(zhuǎn)成blob數(shù)據(jù)對(duì)象 var blob = new Blob([content], { type: "text/plain;charset=utf-8" }); //第二步 => 文件數(shù)據(jù) 轉(zhuǎn)為可以 下載 的地址路徑 改路徑指向文件數(shù)據(jù) /** * objectURL = URL.createObjectURL(object); * * object:用于創(chuàng)建 URL 的 File 對(duì)象、Blob 對(duì)象或者 MediaSource 對(duì)象。 * 返回值:一個(gè)DOMString包含了一個(gè)對(duì)象 URL,該 URL 可用于指定源 object的內(nèi)容。 * * 在每次調(diào)用 createObjectURL() 方法時(shí),都會(huì)創(chuàng)建一個(gè)新的 URL 對(duì)象, * 即使你已經(jīng)用相同的對(duì)象作為參數(shù)創(chuàng)建過(guò)。當(dāng)不再需要這些 URL 對(duì)象時(shí),每個(gè)對(duì)象必須通過(guò)調(diào)用 URL.revokeObjectURL() 方法來(lái)釋放。 * * * 與FileReader.readAsDataURL(file)區(qū)別 * 主要區(qū)別 * 通過(guò)FileReader.readAsDataURL(file)可以獲取一段data:base64的字符串 * 通過(guò)URL.createObjectURL(blob)可以獲取當(dāng)前文件的一個(gè)內(nèi)存URL * * 執(zhí)行時(shí)機(jī) * createObjectURL是同步執(zhí)行(立即的) * FileReader.readAsDataURL是異步執(zhí)行(過(guò)一段時(shí)間) * * 內(nèi)存使用 * createObjectURL返回一段帶hash的url,并且一直存儲(chǔ)在內(nèi)存中,直到document觸發(fā)了unload事件(例如:document close)或者執(zhí)行revokeObjectURL來(lái)釋放。 * FileReader.readAsDataURL則返回包含很多字符的base64,并會(huì)比blob url消耗更多內(nèi)存,但是在不用的時(shí)候會(huì)自動(dòng)從內(nèi)存中清除(通過(guò)垃圾回收機(jī)制) * * 優(yōu)劣對(duì)比 * 使用createObjectURL可以節(jié)省性能并更快速,只不過(guò)需要在不使用的情況下手動(dòng)釋放內(nèi)存 * 如果不太在意設(shè)備性能問(wèn)題,并想獲取圖片的base64,則推薦使用FileReader.readAsDataURL * */ let url = window.URL.createObjectURL(blob); //這里你會(huì)看到類似的地址:blob:http://localhost:8080/d2dbbe3f-7466-415b-a2d0-387cff290acb console.log(url); //動(dòng)態(tài)創(chuàng)建a標(biāo)簽 => 模擬觸發(fā)a標(biāo)簽的下載 => 用于將生成的json數(shù)據(jù)下載到本地 let link = document.createElement('a'); link.style.display = "none"; link.href = url; link.setAttribute('download', 'model.json'); document.body.appendChild(link); link.click(); document.body.removeChild(link); window.URL.revokeObjectURL(url); } /* 文件輸出 */ function outputFile(files) { filesData = ''; btnDisabled(saveJsonBtn); handleFiles(files).then(res => { filesData = res; btnCanClick(saveJsonBtn) obj.innerText = JSON.stringify(res, null, 2); }).catch(err => { console.error(err) }) } /* 按鈕可選 */ function btnCanClick(btnObj) { btnObj.removeAttribute('disabled'); } /* 按鈕不可選 */ function btnDisabled(btnObj) { btnObj.setAttribute('disabled', 'disabled'); } </script> </body> </html>
預(yù)覽
以上就是詳解Js 根據(jù)文件夾目錄獲取Json數(shù)據(jù)輸出demo的詳細(xì)內(nèi)容,更多關(guān)于Js獲取Json數(shù)據(jù)輸出的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
前端傳遞參數(shù)時(shí)form-data和json的區(qū)別詳解
前端可以通FormData對(duì)象實(shí)現(xiàn)表單形式提交數(shù)據(jù),下面這篇文章主要給大家介紹了關(guān)于前端傳遞參數(shù)時(shí)form-data和json區(qū)別的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-11-11JS中關(guān)于事件處理函數(shù)名后面是否帶括號(hào)的問(wèn)題
JS中的事件處理(事件綁定)就是讓某種或某些事件觸發(fā)某些活動(dòng)。有兩種常見(jiàn)的形式,分別是DOM Level 0 和DOM Level 2。今天總結(jié)一個(gè)關(guān)于事件處理程序的小細(xì)節(jié)。感興趣的朋友一起學(xué)習(xí)吧2016-11-11JS實(shí)現(xiàn)中英文混合文字溢出友好截取功能
這篇文章主要介紹了JS實(shí)現(xiàn)中英文混合文字溢出友好截取功能,通常會(huì)用到j(luò)s的 substr 或者 substring方法, 以及 字符串的length屬性。需要的朋友可以參考下2018-08-08深入理解javascript嚴(yán)格模式(Strict Mode)
Strict mode是JavaScript1.8.5引進(jìn)的技術(shù),但還沒(méi)有瀏覽器確實(shí)可靠的實(shí)現(xiàn)了嚴(yán)格模式,所以使用時(shí)要小心并且多測(cè)試。Strict mode可以應(yīng)用于整個(gè)腳本,也可以適合于單個(gè)函數(shù)。2014-11-11JavaScript數(shù)組常用方法解析及數(shù)組扁平化
這篇文章主要介紹了JavaScript數(shù)組常用方法解析及數(shù)組扁平化,數(shù)組作為在開(kāi)發(fā)中常用的集合,除了for循環(huán)遍歷以外,還有很多內(nèi)置對(duì)象的方法,包括map,以及數(shù)組篩選元素filter等2022-07-07JS+CSS相對(duì)定位實(shí)現(xiàn)的下拉菜單
這篇文章主要介紹了JS+CSS相對(duì)定位實(shí)現(xiàn)的下拉菜單,涉及JavaScript結(jié)合css的定位技術(shù)實(shí)現(xiàn)下拉菜單的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-10-10ES6的函數(shù)rest參數(shù)使用小結(jié)
這篇文章主要介紹了ES6的函數(shù)rest參數(shù)用法,通過(guò)一個(gè)rest參數(shù)代替arguments變量的例子,對(duì)ES6?rest參數(shù)用法講解的非常詳細(xì),需要的朋友可以參考下2023-08-08javascript變量作用域使用中常見(jiàn)錯(cuò)誤總結(jié)
剛看了一篇文章對(duì)js作用域的理解又會(huì)上升到一個(gè)新的臺(tái)階,javascript里變量作用域是個(gè)經(jīng)常讓人頭痛抓狂的問(wèn)題,接下來(lái)對(duì)經(jīng)常遇到又容易出錯(cuò)的情況進(jìn)行了簡(jiǎn)單總結(jié),感興趣的各位可以參考下哈2013-03-03微信小程序?qū)崿F(xiàn)歷史搜索功能的全過(guò)程(h5同理)
最近在使用微信小程序開(kāi)發(fā)的時(shí)候遇到了一個(gè)需求,需要實(shí)現(xiàn)歷史搜索記錄的功能,所以下面這篇文章主要給大家介紹了關(guān)于微信小程序?qū)崿F(xiàn)歷史搜索功能(h5同理)的相關(guān)資料,需要的朋友可以參考下2022-12-12