循环遍历 JSON 数据以生成 HTML

Looping through JSON Data to Generate HTML

本文关键字:HTML 数据 遍历 JSON 循环      更新时间:2023-09-26

我有如下所示的JSON数据:

data = {
  "tennis": [{
    "Description": "Insert description here.",
    "Price": 379.99,
    "ProductName": "Babolat Play Pure Drive",
  }, {
    "Description": "Insert description here.",
    "Price": 199.99,
    "ProductName": "Yonex AI 98 Tennis Racquet",
  }],
  "basketball": [{
    "Description": "Insert description here.",
    "Price": 64.99,
    "ProductName": "Wilson NCAA Solution Official Game Basketball",
  }, {
    "Description": "Insert description here.",
    "Price": 59.99,
    "ProductName": "Spalding NBA NeverFlat Size 7 Composite Leather Basketball",
  }]
}

我正在使用这些数据来生成 HTML,因此它看起来格式正确且易于用户阅读。我这样做的方法是创建一个 for 循环来阅读网球和篮球类别。例如:

for (var i = 0; i < data.tennis.length; i++) {
  tennisProducts.push(data.tennis[i]);
  var tennisProductsTitle = tennisProducts[i].ProductName;
  var tennisProductsDescription = tennisProducts[i].Description;
  var tennisProductsPrice = tennisProducts[i].Price;
  var badge = document.createElement('div');
  badge.className = 'badge';
  badge.innerHTML =
    '<h1>' + tennisProductsTitle + '</h1>' +
    '<h2>' + tennisProductsDescription + '</h1>' +
    '<div class="options-only-phone">' +
    '<a class="service-provider-call" href="#" target="_blank"> Buy for $' + tennisProductsPrice + '</a>';
  document.getElementById('tennis-products-list').appendChild(badge);
}

如何创建一个可以读取两个(或多个)类别的 for 循环?

这是我在这个JSFiddle中的工作示例:https://jsfiddle.net/dsk1279b/1

双循环,一个用于迭代对象属性,下一个用于迭代数组:

for (var key in data) {
    for (var i = 0; i < data[key].length; i++) {
        //HTML logic
    }
}

最终代码:

for (var key in data) {
    for (var i = 0; i < data[key].length; i++) {
        var title = data[key][i].ProductName;
        var desc = data[key][i].Description;
        var price = data[key][i].Price;
        var badge = document.createElement('div');
        badge.className = 'badge';
        badge.innerHTML =
            '<h1>' + title + '</h1>' +
            '<h2>' + desc + '</h1>' +
            '<div class="options-only-phone">' +
            '<a class="service-provider-call" href="#" target="_blank"> Buy for $' + price + '</a>';
        //I gave the div the same ID's as the keys in the object for ease
        document.getElementById(key).appendChild(badge);
    }
}

data = {
  "tennis": [{
    "Description": "Insert description here.",
    "Price": 379.99,
    "ProductName": "Babolat Play Pure Drive",
  }, {
    "Description": "Insert description here.",
    "Price": 199.99,
    "ProductName": "Yonex AI 98 Tennis Racquet",
  }],
  "basketball": [{
    "Description": "Insert description here.",
    "Price": 64.99,
    "ProductName": "Wilson NCAA Solution Official Game Basketball",
  }, {
    "Description": "Insert description here.",
    "Price": 59.99,
    "ProductName": "Spalding NBA NeverFlat Size 7 Composite Leather Basketball",
  }]
}
for (var key in data) {
  for (var i = 0; i < data[key].length; i++) {
    var title = data[key][i].ProductName;
    var desc = data[key][i].Description;
    var price = data[key][i].Price;
    var badge = document.createElement('div');
    badge.className = 'badge';
    badge.innerHTML =
      '<h1>' + title + '</h1>' +
      '<h2>' + desc + '</h1>' +
      '<div class="options-only-phone">' +
      '<a class="service-provider-call" href="#" target="_blank"> Buy for $' + price + '</a>';
    document.getElementById(key).appendChild(badge);
  }
}
body {
  font-family: Arial, sans-serif;
  line-height: 125%;
}
h1 {
  font-size: 0.875em;
  padding: 0;
  margin: 0;
}
h2,
a {
  font-size: 0.750em;
  padding: 0;
  margin: 0;
  font-weight: normal;
}
a:hover {
  text-decoration: none;
}
.badge {
  border-radius: 2px;
  border: 1px solid rgba(0, 0, 0, 0.15);
  padding: 12px;
  margin: 12px 0;
}
.badge:hover {
  border: 1px solid rgba(0, 0, 0, 0.3);
}
<div id="tennis">
</div>
<hr>
<div id="basketball">
</div>

tymeJV 有一个很好的方法,但这可以更容易。

for(var product in data) {
    // logic
}

如果您查看数据,您会发现我们已经以键/值形式迭代了一个对象。由于每个键都有项数组,因此可以使用 Array.forEach() 函数。

for(var product in data) {
    // current is the current object in the array
    data[product].forEach(function(current){
        //HTML logic
    })
}

您更改了附加 html 模板的位置,因此我建议将数据对象更新为如下所示:

data = {
  "tennis": {
    "products: [
        {
            "Description": "Insert description here.",
            "Price": 379.99,
            "ProductName": "Babolat Play Pure Drive"
        }, 
        {
            "Description": "Insert description here.",
            "Price": 199.99,
            "ProductName": "Yonex AI 98 Tennis Racquet"
        }
    ],
    "templateTarget": '#tennis-products-list'
  }
  "basketball": 
    "products":  [
        {
            "Description": "Insert description here.",
            "Price": 64.99,
            "ProductName": "Wilson NCAA Solution Official Game Basketball"
        }, 
        {
            "Description": "Insert description here.",
            "Price": 59.99,
            "ProductName": "Spalding NBA NeverFlat Size 7 Composite Leather Basketball"
        }
    ],
      "templateTarget": '#basketball-products-list'
}

类似的东西将允许你这样做:

for(var product in data) {
    // current is the current object in the array
    product.forEach(function(current){
        var badge = document.createElement('div');
        badge.className = 'badge';
        badge.innerHTML =
          '<h1>' + current.productName + '</h1>' +
          '<h2>' + current.description + '</h1>' +
          '<div class="options-only-phone">' +
          '<a class="service-provider-call" href="#" target="_blank"> Buy for $' + current.price +  '</a>';
        document.getElementById(current.templateTarget).appendChild(badge);
    })
}

这可以通过将巨大的 html 字符串隐藏在带有 type="text/x-template"script 标签中(因为浏览器忽略它不理解的脚本类型)并通过引用脚本标签上的 id 属性来使用 innerHTML 函数抓取它。

希望对您有所帮助!

将数据

平展为单个值数组,并将 category 作为属性:

var _data = Object.keys(data).reduce(
              (m,c) => m.concat(data[c].map(
                (i) => (i.category = c) && i))
           , []);
console.log(_data);

对 UI 使用扁平数组:

_data.forEach((d) => {
  var badge = document.createElement('div');
  badge.className = 'badge';
  badge.innerHTML = [
    '<h1>',
    d.ProductName,
    '</h1><h2>',
    d.Description,
    '</h1><div class="options-only-phone">',
    '<a class="service-provider-call" href="#" target="_blank"> Buy for $',
    d.Price,
    '</a>'].join('');
  document.getElementById(d.category + '-products-list').appendChild(badge);
})

'use strict';
var data = {
  "tennis": [{
    "Description": "Insert description here.",
    "Price": 379.99,
    "ProductName": "Babolat Play Pure Drive",
  }, {
    "Description": "Insert description here.",
    "Price": 199.99,
    "ProductName": "Yonex AI 98 Tennis Racquet",
  }],
  "basketball": [{
    "Description": "Insert description here.",
    "Price": 64.99,
    "ProductName": "Wilson NCAA Solution Official Game Basketball",
  }, {
    "Description": "Insert description here.",
    "Price": 59.99,
    "ProductName": "Spalding NBA NeverFlat Size 7 Composite Leather Basketball",
  }]
}

var _data = Object.keys(data).reduce((m,c) => m.concat(data[c].map((i) => (i.category = c) && i) ), []);
console.log(_data);

_data.forEach((d) => {
  var badge = document.createElement('div');
  badge.className = 'badge';
  badge.innerHTML = [
    '<h1>',
    d.ProductName,
    '</h1><h2>',
    d.Description,
    '</h1><div class="options-only-phone">',
    '<a class="service-provider-call" href="#" target="_blank"> Buy for $',
    d.Price,
    '</a>'].join('');
  document.getElementById(d.category + '-products-list').appendChild(badge);
})
body {
  font-family: Arial, sans-serif;
  line-height: 125%;
}
h1 {
  font-size: 0.875em;
  padding: 0; margin: 0;
}
h2, a {
  font-size: 0.750em;
  padding: 0; margin: 0;
  font-weight: normal;
}
a:hover {
  text-decoration: none;
}
.badge {
  border-radius: 2px;
  border: 1px solid rgba(0, 0, 0, 0.15);
  padding: 12px;
  margin: 12px 0;
}
.badge:hover {
    border: 1px solid rgba(0, 0, 0, 0.3);
}
<div id="tennis-products-list">
</div>
<hr>
<div id="basketball-products-list">
</div>