<div class="btns"><button id="addbtn">Add Person</button><button id="rmvbtn">Remove Person</button><button id="rvlbtn">Reveal Clowns</button> <span class="counts">Humans: <span id="human-count">0</span> Zombies: <span id="zombie-count">0</span> Clowns: <span id="clown-count">0</span></div>
<div class="humans" data-type="humans">
  <postapocalyptic-person></postapocalyptic-person>
  <postapocalyptic-person></postapocalyptic-person>
  <postapocalyptic-person></postapocalyptic-person>
</div>
<div class="zombies" data-type="zombies">
  <postapocalyptic-person></postapocalyptic-person>
  <postapocalyptic-person></postapocalyptic-person>
  <postapocalyptic-person></postapocalyptic-person>
</div>
* {
  box-sizing: border-box;
}
body {
  display: flex;
  flex-wrap: wrap;
  margin: 0;
  --btn-height: 3em;
}
.btns {
  width: 100%;
  padding: 0.5em;
  height: var(--btn-height);
  text-align: center;
}
button {
  height: 3em;
  padding: 0.75em;
  background-color: #960b0b;
  color: #fff;
  border: none;
  border-radius: 0.5em;
  text-align: center;
}
.humans,
.zombies {
  width: 50%;
  min-height: calc(100vh - var(--btn-height));
  padding: 2em;
  background-color: #ddd;
}
.zombies {
  background-color: #ded;
}

.counts {
  margin-left: 1em;
}
.counts span {
  min-width: 1em;
  border: 1px solid #960b0b;
  padding: 0.25em;
  margin-right: 0.5em;
}
customElements.define(
  "postapocalyptic-person",
  class extends HTMLElement {
    constructor() {
      super();
      const shadowRoot = this.attachShadow({ mode: "open" });
    }

    static get observedAttributes() {
      return ["data-clown"];
    }
    connectedCallback() {
      let image = document.createElement("img");
      if (this.parentNode.dataset.type == "humans") {
        image.src = "https://assets.codepen.io/1804713/lady.png";
        this.shadowRoot.appendChild(image);
        let humancount = document.getElementById("human-count");
        humancount.innerHTML = parseInt(humancount.textContent) + 1;
      } else if (this.parentNode.dataset.type == "zombies") {
        image.src = "https://assets.codepen.io/1804713/ladyz.png";
        this.shadowRoot.appendChild(image);
        let zombiecount = document.getElementById("zombie-count");
        zombiecount.innerHTML = parseInt(zombiecount.textContent) + 1;
      }
    }
    disconnectedCallback() {
      let image = this.shadowRoot.querySelector("img");
      if (image.src == "https://assets.codepen.io/1804713/lady.png") {
        let humancount = document.getElementById("human-count");
        humancount.innerHTML = parseInt(humancount.textContent) - 1;
      } else if (image.src == "https://assets.codepen.io/1804713/ladyz.png") {
        let zombiecount = document.getElementById("zombie-count");
        zombiecount.innerHTML = parseInt(zombiecount.textContent) - 1;
      } else if (
        image.src == "https://assets.codepen.io/1804713/ladyc.png" ||
        image.src == "https://assets.codepen.io/1804713/ladyzc.png"
      ) {
        let clowncount = document.getElementById("clown-count");
        clowncount.innerHTML = parseInt(clowncount.textContent) - 1;
      }
    }
    attributeChangedCallback(name, oldValue, newValue) {
      let image = this.shadowRoot.querySelector("img");
      if (name="data-clown" && this.dataset.clown && image) {
        let clowncount = document.getElementById("clown-count"),
          humancount = document.getElementById("human-count"),
          zombiecount = document.getElementById("zombie-count");
        if (image.src.indexOf("lady.png") != -1) {
          image.src = "https://assets.codepen.io/1804713/ladyc.png";
          this.shadowRoot.appendChild(image);
          clowncount.innerHTML = parseInt(clowncount.textContent) + 1;
          humancount.innerHTML = parseInt(humancount.textContent) - 1;
        } else if (image.src.indexOf("ladyz.png") != -1) {
          image.src = "https://assets.codepen.io/1804713/ladyzc.png";
          this.shadowRoot.appendChild(image);
          clowncount.innerHTML = parseInt(clowncount.textContent) + 1;
          zombiecount.innerHTML = parseInt(zombiecount.textContent) - 1;
        }
      }
    }
  }
);

document.getElementById("addbtn").addEventListener("click", function () {
  let zombienest = document.querySelector(".zombies"),
    humancamp = document.querySelector(".humans");
  if (Math.random() > 0.5) {
    zombienest.appendChild(document.createElement("postapocalyptic-person"));
  } else {
    humancamp.appendChild(document.createElement("postapocalyptic-person"));
  }
});
document.getElementById("rmvbtn").addEventListener("click", function () {
  let zombienest = document.querySelector(".zombies"),
    humancamp = document.querySelector(".humans");
  if (Math.random() > 0.5) {
    if (zombienest.lastElementChild) {
      zombienest.lastElementChild.remove();
    }
  } else {
    if (humancamp.lastElementChild) {
      humancamp.lastElementChild.remove();
    }
  }
});

document.getElementById("rvlbtn").addEventListener("click", function () {
  let humans = document.querySelectorAll(".humans postapocalyptic-person"),
    zombies = document.querySelectorAll(".zombies postapocalyptic-person");
  for (let i = 0; i < 3; i++) {
    if (zombies) {
      let index = Math.floor(Math.random() * zombies.length);
      if (zombies[index]) {
        zombies[index].setAttribute("data-clown", true);
      }
    }
    if (humans) {
      let index = Math.floor(Math.random() * humans.length);
      if (humans[index]) {
        humans[index].setAttribute("data-clown", true);
      }
    }
  }
});

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.