Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   Проводник на фронте (https://javascript.ru/forum/dom-window/79442-provodnik-na-fronte.html)

oleg901 10.02.2020 07:11

Проводник на фронте
 
Доброго времени суток, пилил простенький проводничок файлов на фронте и зашел в тупик я не могу продумать гибкий алгоритм хождения папок
Смысл в том что есть два класса:
"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();
	    }
	})


За ранее спасибо за помощь. Этот форум меня не раз выручал и много чему научил похоже мне нужен еще один урок:)

Rise 10.02.2020 08:42

oleg901,
Чувак, наследование (extends) для того и придумали, чтобы не писать одно и тоже, а ты пишешь, смотри строки 24-26 и 44-46. Дальше не разбирался, с такими отступами тем более, что трудно в 21 веке код форматировать?

oleg901 10.02.2020 15:09

Rise,
Допустим, если вам глаз режет я исправил. Теперь можете с алгоритмом помочь?

Malleys 10.02.2020 16:01

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>

oleg901 10.02.2020 16:11

Malleys,
Да, действительно не узнал) Написано красиво, но к сожалению ошибку выводит "SyntaxError: bad method definition" на 57 строку ругается

Malleys 10.02.2020 16:17

Цитата:

Сообщение от oleg901
Да действительно не узнал) Написано красиво, но к сожалению ошибку выводит "SyntaxError: bad method definition" на 57 строку ругается

Firefox? Вам нужно через Babel пропустить код, будет так работать... https://codepen.io/Malleys/pen/yLNNOpN?editors=1010

oleg901 10.02.2020 16:53

Malleys,
Отлично, а есть ли какая нибудь статья(русскоязычная) где рассказывается об этом алгоритме? по подробнее то что вы писали (BlockDevice, CharacterDevice, Socket, SymbolicLink) потому что я смотрю и не могу выкупить, че вы там написали) Мне интересна сама логика кода, если я просто скопирую и оно работает, то это не даст никакого развития

рони 10.02.2020 17:03

Цитата:

Сообщение от oleg901
а есть ли какая нибудь статья(русскоязычная) где рассказывается об этом алгоритме? по подробнее то что вы писали (BlockDevice, CharacterDevice, Socket, SymbolicLink) потому что я смотрю и не могу выкупить, че вы там написали) Мне интересна сама логика кода, если я просто скопирую и оно работает, то это не даст никакого развития

:yes: :yes: :yes:
тоже очень интересно о чём пишет Malleys, :lol:

oleg901 10.02.2020 17:10

рони,
Надеюсь мастер ответит :)

Rise 10.02.2020 19:22

Цитата:

Сообщение от oleg901
Допустим, если вам глаз режет я исправил. Теперь можете с алгоритмом помочь?

Хорошо
                                                                        что

                    тебе
                                                                                                    ничего
                                            не
           режет

                                                               но
                            зачем

                                                                                    мне
                 помогать
                                                                                                    таким
...


Часовой пояс GMT +3, время: 19:44.