gpt4 book ai didi

Javascript - HTML 中的对象循环和组织数据

转载 作者:行者123 更新时间:2023-12-01 02:25:33 25 4
gpt4 key购买 nike

我正在尝试递归地循环对象并在 HTML 中以有组织的方式输出数据。下面是我到目前为止所拥有的,但我目前陷入困境,因为我只能输出行,但不能输出缩进级别。 preview 元素中的示例数据是我正在尝试执行的操作的输出表示。

此外,如果有更好的方法来组织/构造数据(通过分组或类似方式),我将不胜感激。

var obj = {
0: {
"Shirts": 0,
"Jeans": 1,
"Brand": "Lorem ipsum"
},
1: {
"Color": {
"blue" : 1,
"red" : 0
},
"Size": {
"Man": {
"small": 1,
"medium": 0,
"large": 0
},
"Women": {
"small": 1,
"medium": 1,
"large": 1
}
}
},
2: {
"Shipping": {
"overNight": "$ 10",
"3 days": "$ 4"
}
},
3: {
"Stock": {
"Man": [
{
"green jeans": 13,
"green shirts": 17,
"green shoes": 21
},
{
"black jeans": 1,
"black shirts": 12,
"black shoes": 53
}
],
"Women": [
{
"green jeans": 2,
"green shirts": 53,
"green shoes": 11
},
{
"black jeans": 6,
"black shirts": 22,
"black shoes": 29
}
]
}
}
}

var dataEl = document.getElementById('data');

var getProperties = function (obj) {
for (var property in obj) {

if (!obj.hasOwnProperty(property)) continue;

if (obj.hasOwnProperty(property) && obj[property] !== null) {

if (obj[property].constructor == Object) {

dataEl.innerHTML += '<div class="row title">' + property + '</div>';
getProperties(obj[property])

} else if (obj[property].constructor == Array) {
dataEl.innerHTML += '<div class="row title">' + property + '</div>';

for (var i = 0; i < obj[property].length; i++) {
getProperties(obj[property][i]);
}

} else {

dataEl.innerHTML += '<div class="row"><span>' + property +'</span>: ' + obj[property] + '</div>';

}

}
}
}
//getProperties(obj);
#data,
#preview {
display: block;
width: 80%;
font-size: 12px;
font-family: Arial, Helvetica;
padding: 10px;
}
#data .row,
#preview .row {
display: inline-block;
width: 100%;
margin-bottom: 2px;
}
#data .row.title,
#preview .row.title {
font-weight: bold;
font-size: 14px;
}
#data .row.indent-1,
#preview .row.indent-1 {
padding-left: 20px;
}
#data .row.indent-2,
#preview .row.indent-2 {
padding-left: 40px;
}
<div id="data"></div>

<!-- This is how it should be structured -->
<div id="preview">

<div class="row"><span>Shirts:</span>0</div>
<div class="row"><span>Jeans:</span>1</div>
<div class="row"><span>Brand:</span>Lorem ipsum</div>

<div class="row title">Color</div>
<div class="row indent-1"><span>blue:</span> 1</div>
<div class="row indent-1"><span>red:</span> 0</div>

<div class="row title">Size</div>
<div class="row title indent-1">Man</div>
<div class="row indent-2"><span>small:</span> 1</div>
<div class="row indent-2"><span>medium:</span> 0</div>
<div class="row indent-2"><span>large:</span> 0</div>
<div class="row title indent-1">Women</div>
<div class="row indent-2"><span>small:</span> 1</div>
<div class="row indent-2"><span>medium:</span> 1</div>
<div class="row indent-2"><span>large:</span> 1</div>

<div class="row title">Shipping</div>
<div class="row indent-1"><span>overNight:</span> $ 10</div>
<div class="row indent-1"><span>3 days:</span> $ 4</div>

<div class="row title">Stock</div>
<div class="row title indent-1">Man</div>
<div class="row indent-2"><span>green jeans:</span> 13</div>
<div class="row indent-2"><span>green shirts:</span> 17</div>
<div class="row indent-2"><span>green shoes:</span> 21</div>
<div class="row indent-2"><span>black jeans:</span> 1</div>
<div class="row indent-2"><span>black shirts:</span> 127</div>
<div class="row indent-2"><span>black shoes:</span> 53</div>
<div class="row title indent-1">Women</div>
<div class="row indent-2"><span>green jeans:</span> 2</div>
<div class="row indent-2"><span>green shirts:</span> 53</div>
<div class="row indent-2"><span>green shoes:</span> 11</div>
<div class="row indent-2"><span>black jeans:</span> 6</div>
<div class="row indent-2"><span>black shirts:</span> 22</div>
<div class="row indent-2"><span>black shoes:</span> 29</div>

</div>

最佳答案

当您使用递归函数进行 html 构造时,最好不要将结果字符串直接附加到元素中,而是将其存储到变量中并在函数完成后返回它,这使得将结果封装在分组元素中更容易 - 查看与您的源对象兼容的示例方法:

function getProperties(obj, depth) {
depth = depth === undefined ? 0 : depth + 1;
var html = '';

// first handle arrays
if (obj && obj.forEach) {
html += '<div class="list" data-indent="' + depth + '">';
obj.forEach(function (elems, index) {
html += '<div class="item ' + (index % 2 ? 'even' : 'odd') + '" data-index"' + index + '">'
+ getProperties(elems, depth)
+ '</div>';
});
html += '</div>';
}
// the main block (comes after arrays as an array would pass this condition too)
else if (obj && typeof obj === 'object') {
// uncomment if you'd like the whole group enclosed in a parent:
// if (depth === 0) html += '<div class="group">';
Object.keys(obj).forEach(function (key) {
html += '<div class="row" data-indent="' + depth + '">';
if (depth > 0)
html += '<span class="title">' + key + '</span>'
html += getProperties(obj[key], depth)
html += '</div>';
});
// if (depth === 0) html += '</div>';
}
// else the object is just a value
else {
html += '<span class="value">' + obj + '</span>';
}

return html;
}

document.getElementById('data').innerHTML = getProperties(obj);

您可以看到内部迭代(forEach 调用),我只是将另一个 getProperties 调用的结果附加到结果字符串(html变量)。

另一个优点是您不会弄乱“全局状态”(#data 元素的innerHTML),因此无论元素的内容是什么,函数总是返回相同的结果 - 这就是所谓的函数式方法。

这样做后,嵌套元素被包含在父元素中,这使得缩进变得更容易 - 只需在父元素上设置 margin-left (请参阅下面的 css)。

我用迭代函数 (forEach) 替换了 for 循环,以获得更多功能风格,并且在数组的情况下,防止引入中间变量 (i),但这只是偏好问题;而且条件也有点不同,因为最好使用特征检测(该对象是否具有我要使用的功能,例如 forEach?) Object.keys 可以可用于 object 类型的任何对象(这就是为什么数组和 forEach 检测出现在前面,数组也是 object 类型)并且不建议检查构造函数,因为它可能会被自定义构造函数覆盖。

我还添加了深度(这是针对data-indent属性的,它在这里没有任何意义,但您可能会以某种方式利用它)和奇数/偶数类对于数组迭代产生的组,我认为这些是不言自明的。

我更改了 css 类,试图使其更符合上下文,使用此 css 应该可以清楚地表明:

.row {
margin-left: 10px;
}
.title {
font-weight: bold;
}
.value {
padding-left: 10px;
}
.list .odd {
background-color: lightgray;
}
/* just to see how to target a custom attribute */
[data-indent="3"] {
color: red;
}

(自定义属性需要使用 data- 前缀以使其符合 HTML 验证器要求。)

关于Javascript - HTML 中的对象循环和组织数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48839413/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com