🏠 HTML Elements

By Robert Laing

Making a website dynamic boils down to manipulating HTML Elements.

As per tradition with JavaScript, this has turned into a cluttered mess of nearly synonymous things, so 80% of “DHTML” needs to be thrown away to dig up the good stuff.

Importing Elements

You can safely ignore the dozens of getElementBy… and generalize this to two operators provided you understand basic CSS selectors:

  1. querySelector(selector) for a single element. I invariably use ID (prefixed with a hash symbol in CSS selector notation, ie “#IDname”) of which there is only supposed to be one in an HTML document. Even though that’s what I nearly always use, I still prefer it to getElementById(“id”) since I prefer remember general rules to lots of superfluous crap.
  2. querySelectorAll(selectors) for an array of elements. Typically this would be used to group elements sharing a class (prefixed with a dot in CSS selector notation), but thanks to slightly more advanced CSS selector knowledge, this can be done for IDs provided a good naming convention is adopted.

Avoid parents and children

Though I typically want the container of an image to get a larger “tap target”, and similarly the children of a container, especially for games with columns of cards in a container, parentElement and children turn out to be very bad ways of achieving this.

I learnt the hard way that if there’s a typo in the html file — or somebody else (eg a future you) edits the html file and changes the element hierarchy — your JavaScript code breaks.

A better way is to have a system of IDs and using substring matching selectors so as to let querySelector get the parent and querySelectorAll the children.

Matching ID substrings

Several elements can be returned from their IDs by querySelectorAll by using a CSS attribute selector which allow pattern matching.

This notation follows the convention of grep and sed of using ^ for matches starting with a given substring, eg:

img[id^="skyscraper"]

and $ means ending with a given substring:

a[href$=".org"]

and * means the substring appears anywhere

img[id*="hand"]

MDN has more examples.

Converting a NodeList to an array

One gotcha with querySelectorAll is returns some historical relic called a NodeList which needs to be converted into an array literal by either wrapping it in Array.from() or using spread syntax.

Array.from(document.querySelectorAll("img[id*='_']"))
.forEach(function (child) {
  child.remove();
});

[...document.querySelectorAll("img[id*='_']")]
.forEach(function (child) {
  child.remove();
});