Anonymous
Код не работает, как показано на исходном сайте.
Сообщение
Anonymous » 08 июл 2024, 16:01
Я скопировал эту программу просмотра дерева с codepen.io, пытаясь использовать ее на своем статическом веб-сайте. Что странно, это не работает так, как показано на codepen.io. В идеале у нас должна быть возможность разворачивать и сворачивать подкаталоги, но после того, как я скопировал код на свою веб-страницу, все подкаталоги просто отображаются рядом с родительской папкой.
Это так оно должно выглядеть перед раскрытием:
< /p>
Но вот что я на самом деле нашел на своем веб-сайте:
[img]https:// i.sstatic.net/gwd4nyKI.png[/img]
Ниже приведен фрагмент кода, скопированный с codepen.io. Вы можете попробовать ссылку в начале, чтобы увидеть, как он работает в Codepen. io.
Код: Выделить всё
/* shorthand functions (createElement is defined at bottom)*/
const div = (props, ...children) => createElement("div", props, ...children);
const ul = (props, ...children) => createElement("ul", props, ...children);
const li = (props, ...children) => createElement("li", props, ...children);
const i = (props, ...children) => createElement("i", props, ...children);
const span = (props, ...children) => createElement("span", props, ...children);
const header = (props, ...children) =>
createElement("header", props, ...children);
const p = (props, ...children) => createElement("p", props, ...children);
const section = (props, ...children) =>
createElement("section", props, ...children);
const button = (props, ...children) =>
createElement("button", props, ...children);
/* File */
const File = ({ name }) => {
return div(
{ className: "file" },
i({ className: "material-icons", style: "opacity: 0;" }, "arrow_right"),
i({ className: "material-icons" }, "insert_drive_file"),
span(null, name)
);
};
/* Folder */
const openedFolderIcon = "folder_open";
const closedFolderIcon = "folder";
const openedArrowIcon = "arrow_drop_down";
const closedArrowIcon = "arrow_right";
function changeOpened(event) {
const folderHeader = event.target.classList.contains("folder-header")
? event.target
: event.target.parentElement;
const opened = folderHeader.getAttribute("opened") == "true";
const newOpened = !opened;
let icons = folderHeader.querySelectorAll(".material-icons");
icons.forEach(icon => {
if (/arrow/i.test(icon.textContent)) {
icon.textContent = newOpened ? openedArrowIcon : closedArrowIcon;
} else {
icon.textContent = newOpened ? openedFolderIcon : closedFolderIcon;
}
});
try {
const sibling = folderHeader.nextElementSibling;
if (newOpened) {
sibling.classList.remove("hide");
} else {
sibling.classList.add("hide");
}
} catch (e) {
console.warn(`No sibling of elem ${folderHeader} found ...`);
}
folderHeader.setAttribute("opened", newOpened);
}
const Folder = (props, ...children) => {
const opened = props.opened || false;
const arrowIcon = opened ? openedArrowIcon : closedArrowIcon;
const folderIcon = opened ? openedFolderIcon : closedFolderIcon;
const folderName = props.name || "unknown";
return div(
{ className: "folder" },
header(
{
onClick: changeOpened,
className: "folder-header",
opened: opened
},
i({ className: "material-icons" }, arrowIcon),
i({ className: "material-icons" }, folderIcon),
span(null, folderName)
),
ul({ className: opened ? "" : "hide" }, ...children)
);
};
/* TreeView */
const TreeView = () => {
return section(
{ className: "container" },
Folder(
{ name: "src" },
Folder({ name: "myTest.js" }, File({ name: "whatup.js" })),
File({ name: "justASimpleFile.css" })
),
File({ name: "project.json" })
);
};
const app = document.querySelector("#treeView");
app.appendChild(createElement(TreeView));
/* My react-clone mini library */
function appendChildren(parent, children) {
for (let child of children) {
if (!child) continue;
switch (typeof child) {
case "string":
const el = document.createTextNode(child);
parent.appendChild(el);
break;
default:
parent.appendChild(child);
break;
}
}
}
function setStyle(el, style) {
if (typeof style == "string") {
el.setAttribute("style", style);
} else {
Object.assign(el.style, style);
}
}
function setClass(el, className) {
className.split(/\s/).forEach(element => {
if (element) {
el.classList.add(element);
}
});
}
function setProps(el, props) {
const eventRegex = /^on([a-z]+)$/i;
for (let propName in props) {
if (!propName) continue;
if (propName === "style") {
setStyle(el, props[propName]);
} else if (propName === "className") {
setClass(el, props[propName]);
} else if (eventRegex.test(propName)) {
const eventToListen = propName.replace(eventRegex, "$1").toLowerCase();
el.addEventListener(eventToListen, props[propName]);
} else {
el.setAttribute(propName, props[propName]);
}
}
}
//type, [props], [...children]
function createElement(type, props, ...children) {
if (typeof type === "function") {
return type(props);
} else {
const el = document.createElement(type);
if (props && typeof props === "object") {
setProps(el, props);
}
if (children) {
appendChildren(el, children);
}
return el;
}
}
Код: Выделить всё
/* Tree View */
#treeView {
padding-top: 2em;
padding-right: 0.1em;
padding-bottom: 3em;
overflow: auto;
white-space: nowrap;
}
#treeView span {
display: inline-flex;
vertical-align: middle;
padding-left: 0.3em;
font-size: 1.1rem;
}
#treeView i {
display: inline-flex;
vertical-align: middle;
}
/* File */
.file {
position: relative;
display: block;
cursor: pointer;
}
.file:hover {
background-color: #ccc;
}
/* Folder */
.folder {
display: block;
}
.folder-header {
position: relative;
cursor: pointer;
/* z-index: 999; */
}
.folder-header:hover {
background-color: #ccc;
}
.folder > ul {
padding-left: 0;
margin: 0;
}
Как видите, этот код также не работает на SO.
Что я делаю не так? Как заставить этот фрагмент кода работать так, как показано на рисунке?
Подробнее здесь:
https://stackoverflow.com/questions/787 ... al-website
1720443684
Anonymous
Я скопировал эту программу просмотра дерева с codepen.io, пытаясь использовать ее на своем статическом веб-сайте. Что странно, это не работает так, как показано на codepen.io. В идеале у нас должна быть возможность разворачивать и сворачивать подкаталоги, но после того, как я скопировал код на свою веб-страницу, все подкаталоги просто отображаются рядом с родительской папкой. Это так оно должно выглядеть перед раскрытием: [img]https://i.sstatic.net/M47M0KpB.png[/img] < /p> Но вот что я на самом деле нашел на своем веб-сайте: [img]https:// i.sstatic.net/gwd4nyKI.png[/img] Ниже приведен фрагмент кода, скопированный с codepen.io. Вы можете попробовать ссылку в начале, чтобы увидеть, как он работает в Codepen. io. [code]/* shorthand functions (createElement is defined at bottom)*/ const div = (props, ...children) => createElement("div", props, ...children); const ul = (props, ...children) => createElement("ul", props, ...children); const li = (props, ...children) => createElement("li", props, ...children); const i = (props, ...children) => createElement("i", props, ...children); const span = (props, ...children) => createElement("span", props, ...children); const header = (props, ...children) => createElement("header", props, ...children); const p = (props, ...children) => createElement("p", props, ...children); const section = (props, ...children) => createElement("section", props, ...children); const button = (props, ...children) => createElement("button", props, ...children); /* File */ const File = ({ name }) => { return div( { className: "file" }, i({ className: "material-icons", style: "opacity: 0;" }, "arrow_right"), i({ className: "material-icons" }, "insert_drive_file"), span(null, name) ); }; /* Folder */ const openedFolderIcon = "folder_open"; const closedFolderIcon = "folder"; const openedArrowIcon = "arrow_drop_down"; const closedArrowIcon = "arrow_right"; function changeOpened(event) { const folderHeader = event.target.classList.contains("folder-header") ? event.target : event.target.parentElement; const opened = folderHeader.getAttribute("opened") == "true"; const newOpened = !opened; let icons = folderHeader.querySelectorAll(".material-icons"); icons.forEach(icon => { if (/arrow/i.test(icon.textContent)) { icon.textContent = newOpened ? openedArrowIcon : closedArrowIcon; } else { icon.textContent = newOpened ? openedFolderIcon : closedFolderIcon; } }); try { const sibling = folderHeader.nextElementSibling; if (newOpened) { sibling.classList.remove("hide"); } else { sibling.classList.add("hide"); } } catch (e) { console.warn(`No sibling of elem ${folderHeader} found ...`); } folderHeader.setAttribute("opened", newOpened); } const Folder = (props, ...children) => { const opened = props.opened || false; const arrowIcon = opened ? openedArrowIcon : closedArrowIcon; const folderIcon = opened ? openedFolderIcon : closedFolderIcon; const folderName = props.name || "unknown"; return div( { className: "folder" }, header( { onClick: changeOpened, className: "folder-header", opened: opened }, i({ className: "material-icons" }, arrowIcon), i({ className: "material-icons" }, folderIcon), span(null, folderName) ), ul({ className: opened ? "" : "hide" }, ...children) ); }; /* TreeView */ const TreeView = () => { return section( { className: "container" }, Folder( { name: "src" }, Folder({ name: "myTest.js" }, File({ name: "whatup.js" })), File({ name: "justASimpleFile.css" }) ), File({ name: "project.json" }) ); }; const app = document.querySelector("#treeView"); app.appendChild(createElement(TreeView)); /* My react-clone mini library */ function appendChildren(parent, children) { for (let child of children) { if (!child) continue; switch (typeof child) { case "string": const el = document.createTextNode(child); parent.appendChild(el); break; default: parent.appendChild(child); break; } } } function setStyle(el, style) { if (typeof style == "string") { el.setAttribute("style", style); } else { Object.assign(el.style, style); } } function setClass(el, className) { className.split(/\s/).forEach(element => { if (element) { el.classList.add(element); } }); } function setProps(el, props) { const eventRegex = /^on([a-z]+)$/i; for (let propName in props) { if (!propName) continue; if (propName === "style") { setStyle(el, props[propName]); } else if (propName === "className") { setClass(el, props[propName]); } else if (eventRegex.test(propName)) { const eventToListen = propName.replace(eventRegex, "$1").toLowerCase(); el.addEventListener(eventToListen, props[propName]); } else { el.setAttribute(propName, props[propName]); } } } //type, [props], [...children] function createElement(type, props, ...children) { if (typeof type === "function") { return type(props); } else { const el = document.createElement(type); if (props && typeof props === "object") { setProps(el, props); } if (children) { appendChildren(el, children); } return el; } }[/code] [code]/* Tree View */ #treeView { padding-top: 2em; padding-right: 0.1em; padding-bottom: 3em; overflow: auto; white-space: nowrap; } #treeView span { display: inline-flex; vertical-align: middle; padding-left: 0.3em; font-size: 1.1rem; } #treeView i { display: inline-flex; vertical-align: middle; } /* File */ .file { position: relative; display: block; cursor: pointer; } .file:hover { background-color: #ccc; } /* Folder */ .folder { display: block; } .folder-header { position: relative; cursor: pointer; /* z-index: 999; */ } .folder-header:hover { background-color: #ccc; } .folder > ul { padding-left: 0; margin: 0; }[/code] [code] [/code] Как видите, этот код также не работает на SO. Что я делаю не так? Как заставить этот фрагмент кода работать так, как показано на рисунке? Подробнее здесь: [url]https://stackoverflow.com/questions/78720986/code-not-working-as-shown-on-the-original-website[/url]