Generating huge amounts of HTML

Viewed 124

I am working on a browser game. I have lots of upgrades, crafting, planets, etc that I generate with jS (1 box (or square?) PER EACH item). Here is a mini snippet from my game, displaying my current method of generating HTML

JSFiddle example

I do a simple loop and insert as many boxes as there are upgrades

for(i = 0; i < 9; i ++)

Then, I put a gigantic HTML code block in a function, and use arrays to identify upgrades ID, name, info...

Is this a good practice to generate loads of HTML content? If not, what can I do to improve it?

Also, I started "coding" a game with one main goal to learn JS. If you have better solutions, but they include a lib (jQuery, etc) then you can post it, but I'm going pure jS here. Thanks!

-- Update --

I've been learning lots of JS in the past year. @DoXicK provided a great example a while ago but I didn't understand it then. This is the final rendering method I come up with, thanks to his examples, and I guess I'll stick with it:

JS:

const game = {};
// make our life easier
const $ = key => document.getElementById(key);
const render = (key, str) => $(key).insertAdjacentHTML("beforeend", str);
// a function that returns upgrades html content
const html = self => `
  <div class="some-class" id="${self.id}">
    <h2>${self.name}</h2>
    <p>${self.damage}</p>
  </div>
`;
// object containing each upgrades template
const template = {
  laserGun: {
    id: "laserGun",
    name: "Laser Gun",
    damage: 10
  },
  plasmaGun: {
    id: "plasmaGun",
    name: "Plasma Gun",
    damage: 30
  }
};
// Upgrade class
class Upgrade {
  constructor(upg) {
    this._id = upg.id;
    this._name = upg.name;
    this._damage = upg.damage;
  }

  get id() {return this._id;}
  get name() {return this._name;}
  get damage() {return this._damage;}

  generate() {
    // find div with upgrade id, and inject it's html content inside
    render("upgrade", html(this));
  }

  static make(key) {
    game.upgrade[key] = new Upgrade(template[key]);
    game.upgrade[key].generate();
  }
}

let laserGun = Upgrade.make("laserGun");

HTML:

<div class="upgrade-container" id="upgrade">

I hope you find it helpful!

1 Answers

As i already explained in comments, your code will become quite unmaintainable if you keep it as spaghetti code like that.

I've made an updated example which does the exact same thing as you did, just with a bit of updated javascript and by making a javascript-component out of your "template".

https://jsfiddle.net/7L8e5kmg/3/

class UpgradeBlock {
    constructor(props) {
      this.props = props;
  }
  render() {
    let { Id, Name, Info, Res } = this.props;
    // basically:
    // let Id = this.props.Id;
    // let Name = this.props.Name;
    // etc
    return (`
<div class="hud-item" id="${Id}">
    <img src="client/img/${Id}.png" id="${Id}Img" />
    <div class="hud-tooltip f16 fwhite">
        <div class="hud-tt-header-container">
            <div class="hud-tt-info-container">
                <div class="col-full">${Name}</div>
                <div class="col-half">
                    <img style="vertical-align: text-bottom;" src="img/${Res}16.png" />
                  <span id="${Id}Cost"></span>
                                </div>
                <div class="col-half">
                    +<span id="${Id}dmgPerLv"></span>
                  <img style="vertical-align: text-bottom;" src="client/img/character/dps16.png" />
                                </div>
            </div>
            <div class="hud-tt-lv-container">
                <canvas id="${Id}Bar" width="64px" height="64px"></canvas>
                        </div>
        </div>
        <hr/>
        <div class="hud-tt-info-container">
            <div class="col-half fwhite f16">
                <img style="vertical-align: text-bottom" src="client/img/character/dps16.png" />
              <span id="${Id}Dmg"></span>
            </div>
            <div class="col-half fgrey f10"><span class="fwhite f16" id="${Id}ofTotal"></span> of total</div>
            <div class="col-full fgrey f10">${Info}</div>
            <div class="col-full f10" id="${Id}click"></div>
        </div>
    </div>
</div>
    `)
  }
}

You use it by doing:

let upgrade = {
  Id: 'id', 
  Name: 'name',
  Info: 'info',
  Res: 'res'
};
let html = new UpgradeBlock(upgrade).Render()

For people that do react: yes, it is intended to steer that way.

Related