我正在尝试编写一个函数,该函数基于JSON对象将子级追加到DOM。
我遇到的问题是递归中的最后一个return
“覆盖”其他所有结果,但我不确定为什么。
这是我的代码:
var tags = [{
tag: 'div',
props: [{
'class': 'meetup-container'
}],
children: [{
tag: 'div',
props: [{
class: 'meetup',
itemscope: '',
itemtype: 'http://schema.org/Event'
}],
children: [{
tag: 'p',
props: [{
itemprop: 'event'
}]
}],
}]
}, {
tag: 'a',
props: [{
href: '#'
}]
}]
function buildDom(graph) {
let element;
graph.forEach((node) => {
element = document.createElement(node.tag);
if (node.props && node.props.constructor === Array) {
node.props.forEach((prop) => {
let propNames = Object.keys(prop);
propNames.forEach((propName) => {
return element.setAttribute(propName, prop[propName]);
});
});
}
if (node.children) {
element.appendChild(buildDom(node.children));
// return element.appendChild(buildDom(node.children));
}
});
return element;
}
let elements = buildDom(tags);
基本上,我希望看到的输出是这样:
<div class="meetup-container">
<div class="meetup">
<p itemprop="event"></p>
</div>
</div>
但是我看到的是这个
<p itemprop="event"></p>
但是,如果我console.log
函数的每一步,我都能看到我的函数如何正确地逐步遍历子元素,问题在于它没有按照应有的方式附加它们。
答案 0 :(得分:4)
您的代码有一些缺陷:
graph
中包含多个元素,则仅返回最后一个元素,而不返回预期的元素数组。要解决此问题,请使用map
并返回结果数组。return
中的forEach
语句是没有用的。buildDom
应该返回元素数组,因为它需要一个对象数组(请参阅 1。),因此element.appendChild(buildDom(node.children));
将不再起作用。使用forEach
遍历该数组。话虽这么说
function buildDom(graph) {
return graph.map((node) => {
let element = document.createElement(node.tag);
if (node.props && Array.isArray(node.props)) {
node.props.forEach((prop) => {
let propNames = Object.keys(prop);
propNames.forEach((propName) =>
element.setAttribute(propName, prop[propName])
);
});
}
if (node.children) {
buildDom(node.children).forEach(child => element.appendChild(child));
}
return element;
});
}
示例:
function buildDom(graph) {
return graph.map((node) => {
let element = document.createElement(node.tag);
if (node.props && Array.isArray(node.props)) {
node.props.forEach((prop) => {
let propNames = Object.keys(prop);
propNames.forEach((propName) =>
element.setAttribute(propName, prop[propName])
);
});
}
if (node.children) {
buildDom(node.children).forEach(child => element.appendChild(child));
}
return element;
});
}
let tags = [{"tag":"div","props":[{"class":"meetup-container"}],"children":[{"tag":"div","props":[{"class":"meetup","itemscope":"","itemtype":"http://schema.org/Event"}],"children":[{"tag":"p","props":[{"itemprop":"event"}]}]}]},{"tag":"a","props":[{"href":"#"}]}];
let result = document.getElementById("result"),
elements = buildDom(tags);
elements.forEach(element => result.appendChild(element));
Result: (inspect element to see it)
<div id="result"></div>