10.02.2020, 07:11
|
Аспирант
|
|
Регистрация: 12.08.2018
Сообщений: 54
|
|
Проводник на фронте
Доброго времени суток, пилил простенький проводничок файлов на фронте и зашел в тупик я не могу продумать гибкий алгоритм хождения папок
Смысл в том что есть два класса:
"element" - типа обычного файла;
"Folder" - папка, внутри класса массив с такими же element и Folder(тип файлы и папки);
и
объект "failing" - в нем есть массив который который хранит все! И метод "render" он отрисовывает все на экран.
Кстати класс "Folder" тоже содержит идентичный метод.
У меня получилось добиться того, что я на пример нажимаю на папку и у меня отрисовывает содержимое папки нажимаю многоточие (тип назад) у меня выводится первый уровень. Но мне нужно, что бы все папки внутри папок сколько бы я не создал открывались и при нажатии многоточия поднимался на уровень выше пока не вернется на главную самый верхний уровень.
Вот код:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<link rel="stylesheet" type="text/css" href="style.css" />
</head>
<body>
<script type="text/javascript">
let b = document.getElementsByTagName('body')[0];
class element {
constructor(name) {
this.name = name;
this.size = "Не реализовано!";
this.data = "Не реализовано!";
this.type = "file";
}
}
class Folder extends element {
constructor(name, size, data) {
super(name, size, data);
this.name = name;
this.size = size;
this.data = data;
this.mass = [beack];
this.type = "folder";
}
render() {
b.innerHTML = "";
for (let i = 0; i < this.mass.length; i++) {
let div = document.createElement('div');
b.appendChild(div);
if (this.mass[i].type === "folder") {
div.innerHTML = `<p class="folder" id ="${i}">${this.mass[i].name}</p>`;
}
else {
if (i === 0) {
div.innerHTML = `<p class="beack" id ="${i}"> ${this.mass[i].name}</p>`;
}
else {
div.innerHTML = `<p class="file" id ="${i}"> ${this.mass[i].name}</p>`;
}
}
}
}
}
let beack = {
name: "..."
}
let failing = {
mass: [],
render() {
b.innerHTML = "";
for (let i = 0; i < this.mass.length; i++) {
let div = document.createElement('div');
b.appendChild(div);
if (this.mass[i].type === "folder") {
div.innerHTML = `<p class="folder" id ="${i}">${this.mass[i].name}</p>`;
}
else {
div.innerHTML = `<p class="file" id ="${i}"> ${this.mass[i].name}</p>`;
}
}
}
}
let index = new element("index.html"),
style = new element("style.css"),
direct = new Folder("direct"),
direct1 = new Folder("direct1"),
file1 = new element("file.css"),
file2 = new element("file1.css");
direct1.mass.push(file1);
direct.mass.push(direct1);
failing.mass.push(index);
failing.mass.push(style);
failing.mass.push(direct);
failing.render()
console.log(failing);
document.addEventListener("click", function(e) {
//console.log(e.target);
if (e.target.className === "folder") {
failing.mass[+e.target.attributes.id.value].render();
}
if (e.target.className === "beack") {
failing.render();
}
})
За ранее спасибо за помощь. Этот форум меня не раз выручал и много чему научил похоже мне нужен еще один урок
Последний раз редактировалось oleg901, 10.02.2020 в 15:06.
|
|
10.02.2020, 15:09
|
Аспирант
|
|
Регистрация: 12.08.2018
Сообщений: 54
|
|
Rise,
Допустим, если вам глаз режет я исправил. Теперь можете с алгоритмом помочь?
|
|
10.02.2020, 16:01
|
|
Профессор
|
|
Регистрация: 20.12.2009
Сообщений: 1,714
|
|
oleg901,
Сообщение от oleg901
|
папка, внутри класса массив с такими же element и Folder(тип файлы и папки);
|
Может тогда Folder и File? А кто подумает об BlockDevice, CharacterDevice, Socket, SymbolicLink? Можно вместо этих классов сделать Entry, который описывает вхождение в файловой системе.
Сообщение от oleg901
|
Но мне нужно, что бы все папки внутри папок сколько бы я не создал открывались и при нажатии многоточия поднимался на уровень выше пока не вернется на главную самый верхний уровень.
|
Вот поменял ваш код... (Упс! Кажется вы уже свой код не узнаете!)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<link rel="stylesheet" type="text/css" href="https://cdn.glitch.com/348d485e-4ba6-4841-a41e-5865874b2d66/files.css" />
</head>
<body>
<main id="app"></main>
<script>
/*
это только mockup, напишите в методе fetchDirectoryContent(path)
реальное получение данных папки
*/
const fs = {
"/": [{
mode: 16877,
path: "direct"
}, {
mode: 33204,
path: "index.html"
}, {
mode: 33204,
path: "style.css"
}, {
mode: 33204,
path: "pic.png"
}],
"/direct": [{
mode: 16877,
path: ".."
}, {
mode: 16877,
path: "direct1"
}],
"/direct/direct1": [{
mode: 16877,
path: ".."
}, {
mode: 33204,
path: "file.css"
}, {
mode: 33204,
path: "file1.css"
}],
};
</script>
<script type="module">
import { Component, render, html } from "https://unpkg.com/htm/preact/standalone.module.js";
class Entry {
constructor({ mode, path }) {
this.mode = mode;
this.path = path;
}
/* совместимо с node.js — [url]https://github.com/nodejs/node-v0.x-archive/issues/3045[/url] (т. е. stats.mode)*/
static DIR = 0x4000;
static FILE = 0x8000;
get isFile() {
return (this.mode & Entry.FILE) !== 0;
}
get isDirectory() {
return (this.mode & Entry.DIR) !== 0;
}
get type() {
return this.isFile ? "file" : this.isDirectory ? "directory" : "entry";
}
get extension() {
const dotIndex = this.path.lastIndexOf(".");
return dotIndex !== -1 ? this.path.slice(dotIndex + 1) : "";
}
}
class App extends Component {
state = {
index: "/",
entries: []
}
linkHandler = (entry, path) => event => {
event.preventDefault();
if(entry.isDirectory) {
this.fetchDirectoryContent(path);
}
}
componentDidMount() {
this.fetchDirectoryContent("/");
}
fetchDirectoryContent(path) {
const { pathname } = new URL(path, "file:///");
console.log(pathname);
this.setState({
index: pathname,
entries: fs[pathname.replace(/(?<=..)\/$/g, "")].map(entry => new Entry(entry))
});
}
render() {
const { index, entries } = this.state;
return html`
<header>
<h1>
<i>Index of </i> ${index}
</h1>
</header>
<ul id="files">
${
entries.map(entry => {
const fullEntryPath = [index.replace(/\/$/g, ""), entry.path].join("/");
return html`
<li>
<a
href="#index=${encodeURIComponent(fullEntryPath)}"
class="${entry.type} ${entry.extension}"
onClick=${this.linkHandler(entry, fullEntryPath)}
>${entry.path}</a>
</li>
`
})
}
</ul>
`;
}
}
render(html`<${App} />`, document.getElementById("app"));
</script>
</body>
</html>
Последний раз редактировалось Malleys, 10.02.2020 в 16:10.
|
|
10.02.2020, 16:11
|
Аспирант
|
|
Регистрация: 12.08.2018
Сообщений: 54
|
|
Malleys,
Да, действительно не узнал) Написано красиво, но к сожалению ошибку выводит "SyntaxError: bad method definition" на 57 строку ругается
Последний раз редактировалось oleg901, 10.02.2020 в 16:15.
|
|
10.02.2020, 16:17
|
|
Профессор
|
|
Регистрация: 20.12.2009
Сообщений: 1,714
|
|
Сообщение от oleg901
|
Да действительно не узнал) Написано красиво, но к сожалению ошибку выводит "SyntaxError: bad method definition" на 57 строку ругается
|
Firefox? Вам нужно через Babel пропустить код, будет так работать... https://codepen.io/Malleys/pen/yLNNOpN?editors=1010
|
|
10.02.2020, 16:53
|
Аспирант
|
|
Регистрация: 12.08.2018
Сообщений: 54
|
|
Malleys,
Отлично, а есть ли какая нибудь статья(русскоязычная) где рассказывается об этом алгоритме? по подробнее то что вы писали (BlockDevice, CharacterDevice, Socket, SymbolicLink) потому что я смотрю и не могу выкупить, че вы там написали) Мне интересна сама логика кода, если я просто скопирую и оно работает, то это не даст никакого развития
|
|
10.02.2020, 17:03
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,109
|
|
|
|
10.02.2020, 17:10
|
Аспирант
|
|
Регистрация: 12.08.2018
Сообщений: 54
|
|
рони,
Надеюсь мастер ответит
|
|
10.02.2020, 23:37
|
Аспирант
|
|
Регистрация: 12.08.2018
Сообщений: 54
|
|
Сообщение от Rise
|
Хорошо
что
тебе
ничего
не
режет
но
зачем
мне
помогать
таким
...
|
Заморочился еще так написать) Но аналогия прикольная)
|
|
10.02.2020, 23:39
|
Аспирант
|
|
Регистрация: 12.08.2018
Сообщений: 54
|
|
В общем и целом всем спасибо за помощь! Тема закрыта)
|
|
|
|