通过 JavaScript 仿Linux终端控制台,假定目录结构由 json格式数据
描述
root: {
pathA: {
game: {
},
toy: {
},
},
pathB: {
project1: {
},
project2: {
},
},
pathC: {
image: {
},
data: {
},
},
}
文件代码
两个文件,一个是 html,一个是 js
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Rosetta Interview: VirtualConsole</title>
<style>
html,
body {
height: 100vh;
width: 100vw;
margin: 0;
padding: 0;
overflow: hidden
}
#console {
color: #d3d3d3;
background-color: #000;
border: 1px solid #fff;
border-radius: 10px;
flex-direction: column;
align-items: stretch;
padding: 7px 13px;
display: flex;
position: absolute;
inset: 3em;
overflow-y: scroll
}
#console>div:last-child {
display: flex
}
#console>div:last-child:before {
content: "$root > "
}
#console>div:last-child input {
color: #fff;
background-color: #0000;
border: none;
outline: none;
flex: 1
}
#console #history .cmd:before {
content: "$root > ";
font-weight: 700;
}
</style>
<script type="module">
class n {
}
class e extends n {
async read() {
return ''
}
}
class t extends n {
async write(n) {
this.format && (n = this.format(n)), o(n)
}
}
// n:command/first_arg, e:{ className }/undefined
function o(n, e) {
const t = document.createElement("div");
for (const [n, o] of Object.entries(e || {
})) t[n] = o;
t.innerText = n, c("history").append(t), c("input").scrollIntoView()
}
function c(n) {
return document.getElementById(n)
}
window.addEventListener("load", (async function n() {
window.removeEventListener("load", n);
const r = await async function () {
return new Promise((function (n, e) {
const t = document.createElement("script");
t.src = "./sh.js", t.onload = function () {
t.remove()
},
document.head.append(t), document.addEventListener("sh.js", (function e(t) {
document.removeEventListener("sh.js", e);
const o = t.detail;
n(o)
}))
}))
}(), s = new e, i = new t, d = new t;
c("console")?.addEventListener("click", (function () {
const n = document.getSelection();
n && n.toString() || c("input")?.focus()
}));
c("input")?.addEventListener("keyup",
(function (n) {
if ("Enter" !== n.code) return;
if (!(n.currentTarget instanceof HTMLInputElement)) return;
const e = n.currentTarget.value.trim();
if (!e) return;
n.currentTarget.value = "";
o(e, {
className: "cmd"
});