简体   繁体   中英

Looping through Javascript Object and adding to HTML Div

I am working on a game and have run into a problem that I have been stuck on for hours. I have an object, and I want to write a loop which will take all the values in this object, and stick them into an html div. The way I am doing this is, I have taken a div, I am cloning it and giving all the child elements new values. Then I want to use the DOM manipulation to insert the values from one key, into a div with a heading and two paragraphs. Here is the code.

Index.html

<div id = "all_asset" style = "display: none;">
    <div class = "touch_box col-sm-12" style = "height: 150px; display: none;" id = "asset_touchbox">
        <br><h id = "asset_name"></h>
        <p1 id = "asset_price"></p1><hr>
        <p id = "asset_age"></p><hr>
    </div>    
</div>

play.js

function assetsList(){
    Object.keys(assets).forEach(key => {
        for (var i = 1; i < Object.keys(assets).length; i++){
    
            //duplicate box
            var list_box = document.getElementById("asset_touchbox");
            var clone_box = list_box.cloneNode(true);
            clone_box.id = "list_assets" + String(i);
            document.getElementById("all_asset").appendChild(clone_box);

            //get id of child elements
            clone_box.getElementsByTagName('h')[0].id = "asset_name" + String(i);
            clone_box.getElementsByTagName('p1')[0].id = "asset_price" + String(i);
            clone_box.getElementsByTagName('p')[0].id = "asset_age" + String(i);
            list_box.parentNode.appendChild(clone_box);
            //show box
            clone_box.style.display = "block";

            var asset_name = assets[key][0];
            var asset_age = assets[key][1];
            var asset_price = assets[key][2];

            document.getElementById("asset_name" + String(i)).innerHTML = asset_name;
            document.getElementById("asset_price" + String(i)).innerHTML = asset_age;
            document.getElementById("asset_age" + String(i)).innerHTML = asset_price;
        }
      });      
}

Javascript Object

//asset name, asset age, asset cost
assets = {1: ["Boat", 0, "10000"], 2: ["Carriage", 0, "10000"]}

So what I pretty much want to do is - Create two divs, each one has the information from each key. I hope I made sense. Please let me know if I didn't. Thanks!

You can use class to simplify the code.

Here is an example:

 // The original object given by you const givenAssets = { 1: ['Boat', 0, '10000'], 2: ['Carriage', 2, '30000'] }; // Get #all_asset const assetContainer = document.querySelector('#all_asset'); // Define a class class Asset { // Set parameters constructor(id, name, price, age) { this.id = id; this.name = name; this.price = price; this.age = age; } // Create HTML addHtml() { // HTML elements as string let html = ` <div class="touch_box col-sm-12" id="list_asset${this.id}"> <br> <h4 id="asset_name${this.id}">${this.name}</h4> <p id="asset_price${this.id}">${this.price}</p> <hr> <p id="asset_age${this.id}">${this.age}</p> <hr> </div>`; // Add HTML element before the end of #all_asset assetContainer.insertAdjacentHTML('beforeend', html); } } // Make instances and put them into an array let assets = []; for (const key in givenAssets) { assets.push(new Asset(key, givenAssets[key][0], givenAssets[key][1], givenAssets[key][2])) } // Execute.addHtml() on each asset one by one. assets.forEach(asset => asset.addHtml());
 <div id="all_asset"></div>

Personally, I'd build the asset html inside your forEach function instead of cloning placeholder html. The code below should create the structure you're looking for. Good luck!

index.html

<div id="all_asset"/>

play.js

const assets = {
  1: ["Boat", 0, "10000"],
  2: ["Carriage", 0, "10000"]
}

function assetsList() {
  Object.keys(assets).forEach(key => {
    // get current asset data
    const assetData = assets[key];
    // create asset container
    const container = document.createElement("div");
    // create and append asset header
    const header = document.createElement('h1');
    header.appendChild(document.createTextNode(assetData[0]))
    // create and append first p
    const p1 = document.createElement('p')
    p1.appendChild(document.createTextNode(assetData[1]))
    // crreate and append second p
    const p2 = document.createElement('p')
    p2.appendChild(document.createTextNode(assetData[2]))
    // fill out the asset container
    container.appendChild(header)
    container.appendChild(p1)
    container.appendChild(p2)
    // append the whole thing to the parent
    document.getElementById("all_asset").appendChild(container);
  })
};

You may want to consider refactoring your representation of the assets as an array of objects. For example,

let assets = [
  {
    name: 'boat',
    age: 0,
    price: 10000,
  },
  {
    name: 'carriage',
    age: 0,
    price: 10000,
  },
];

Following your initial idea of using the forEach method to iterate over the assets, you could dynamically insert a div for every asset.

assets.forEach(({ name, age, price }) => {
  let touchBox = document.createElement('div');
  touchBox.classList.add('touch_box', 'col-sm-12');
  touchBox.id = 'asset_touchbox';
  touchBox.style.height = '150px';

  let nameElt = document.createElement('h5');
  nameElt.id = 'asset_name';
  nameElt.innerHTML = name;

  let priceElt = document.createElement('p');
  priceElt.id = 'asset_price';
  priceElt.innerHTML = price;

  let ageElt = document.createElement('p');
  ageElt.id = 'asset_age';
  ageElt.innerHTML = age;

  touchBox.appendChild(nameElt);
  touchBox.appendChild(priceElt);
  touchBox.appendChild(ageElt);

  document.querySelector('#list_box').appendChild(touchBox);
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM