我有一个多维数组categories
,并且正在使用menuToElement
函数遍历该数组。
它将array
及其子元素的所有元素取回ul
中。代码可以正常工作,但是我不知道是如何仅遍历数组的一个元素及其所有子元素。
例如,我要执行的操作仅是循环搜索引擎元素及其所有子元素和所有子元素数组。我的问题是:我使用的for...of
循环是否有可能实现此目标,因为我尝试遍历类别索引并且它说这是不可迭代的。
function menuToElement(menu) {
const ul = document.createElement("ul");
for (const item of menu) {
const li = document.createElement("li");
if (Object(item) === item) {
li.textContent = item.text + ' \u25BD';
li.appendChild(menuToElement(item.children));
} else {
li.textContent = item;
}
ul.appendChild(li);
}
return ul;
}
var categories = [{
text: "engine",
children: [1, 2, 3, {
text: "piston",
children: [4, 5, 6, {
text: "piston",
children: [4, 5, 6]
}]
}]
}, {
text: "tire",
children: [7, 8, 9]
}];
const ul = menuToElement(categories);
document.getElementById("menu").appendChild(ul);
li>ul {
display: none;
}
li:hover>ul {
display: block;
}
<div id="menu"></div>
答案 0 :(得分:0)
首先,我们从一些帮助我们的生活变得更轻松的助手开始:elem
和text
-
const elem = (tag, ...children) =>
{ const node = document.createElement(tag)
children.forEach(node.appendChild.bind(node))
return node
}
const text =
document.createTextNode.bind(document)
const doc =
elem
( "article" // <article>
, elem("p", text("wash hand")) // <p>wash hand</p>
, elem("p", text("read book")) // <p>read book</p>
, elem("p", text("stay safe")) // <p>stay safe</p>
) // </article>
document.body.appendChild(doc)
article { border: 1px solid tomato; }
p { border: 1px solid dodgerblue; }
接下来,我们定义如何将一个菜单项转换为菜单节点toMenu1
-
item
是对象,则返回带有LI
的{{1}}并在item.text
上调用toMenu
item.children
不是是一个对象。在这种情况下,只需返回带有纯文本的item
LI
我们还没有写const toMenu1 = (item = {}) =>
Object(item) === item
? elem('li', text(`${item.text} \u25BD`), toMenu(item.children)) // 1
: elem('li', text(item)) // 2
,但是在上面我们看到它期望有一系列的项目。编写此函数比上一个要容易-
toMenu
,其中每个项目都使用UL
进行转换toMenu1
在继续之前,请展开下面的代码片段,以在您自己的浏览器中验证结果-
const toMenu = (all = []) =>
elem('ul', ...all.map(toMenu1)) // 1
const elem = (tag, ...children) =>
{ const node = document.createElement(tag)
children.forEach(node.appendChild.bind(node))
return node
}
const text =
document.createTextNode.bind(document)
const toMenu1 = (item = {}) =>
Object(item) === item
? elem('li', text(`${item.text} \u25BD`), toMenu(item.children))
: elem('li', text(item))
const toMenu = (all = []) =>
elem('ul', ...all.map(toMenu1))
var categories = [{
text: "engine",
children: [1, 2, 3, {
text: "piston",
children: [4, 5, 6, {
text: "piston",
children: [4, 5, 6]
}]
}]
}, {
text: "tire",
children: [7, 8, 9]
}];
const ul = toMenu(categories)
document.getElementById("menu").appendChild(ul)
li>ul {
display: none;
}
li:hover>ul {
display: block;
}
现在要回答您的特定问题:我们可以仅使用一个输入项来构建递归菜单吗?
您可以通过以下两种方法之一来执行此操作。 1)仅抓取您关心的物品-
<div id="menu"></div>
或者2)通过使用const ul = toMenu([ categories[0] ]) // just the first category
// <ul>
// <li>engine<ul>...</ul></li>
// </ul>
-
Array.prototype.filter
奖金:const ul = toMenu(categories.filter(c => c.text === "engine"))
// <ul>
// <li>engine<ul>...</ul></li>
// </ul>
和toMenu1
之间的特殊关系称为mutual recursion。 toMenu
呼叫toMenu1
,后者呼叫toMenu
,呼叫toMenu1
,依此类推...
答案 1 :(得分:-2)
为此,您需要使用
Array.from()
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from
因此它用于转换DOM节点(或子节点) 如果您想要更多解释性的评论,请