【问题标题】:Looping through JSON Data to Generate HTML循环通过 JSON 数据生成 HTML
【发布时间】:2016-04-26 18:25:16
【问题描述】:

我的 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

【问题讨论】:

    标签: javascript html json


    【解决方案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>

    【讨论】:

    • 谢谢。绝对是一种更清洁的方法。
    【解决方案2】:

    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);
        })
    }
    

    这可以通过使用type="text/x-template" 隐藏在script 标记中的巨大html 字符串来进一步优化(因为浏览器会忽略它不理解的脚本类型)并通过引用@987654328 使用innerHTML 函数来获取它脚本标签上的@属性。

    希望有帮助!

    【讨论】:

      【解决方案3】:

      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>

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-12-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-10-10
        • 2020-01-12
        • 1970-01-01
        相关资源
        最近更新 更多