Beyond appendChild: Better convenience methods for HTML
Tags: javascript, html
Published: 2019-06-09 00:09:35

---
title: Beyond appendChild: Better convenience methods for HTML
published: true
description: Sometimes, we all just have to write vanilla JS. Make it easier by updating your repertoire! 
canonical_url: https://whistlr.info/2019/better-html-convenience/
tags: javascript, html
series: Blog-A-Day in June
---

I've built on the web for a while now. So long that when I'm writing vanilla HTML/JS, my go-to has always been `.appendChild()` to add new HTML elements, and a huge series of `createElement` calls along with it.

But there's actually some lesser-known convenience methods that we can use now (well, in a post-IE11 world, where all devs should be). 🌎👍 I'm not arguing against your framework or components, but sometimes, you _just have to write vanilla JS_. 🍦

## One-Line Element Creation

I confess 😅 that this isn't really one line, but it's one _statement_:

```js
const el = Object.assign(document.createElement('div'), {
  textContent: `Your div now has text`,
  className: 'and-is-classy',
});
```

The helper `Object.assign` wasn't available in IE11.

## Remove Self

This one is pretty well-known.

```js
const el = document.getElementById('something');
el.remove();   // instead of el.parentNode.removeChild(el)
```

## Insert Element _or_ Text

The `.append()` method can append any real elements, or it will automatically create a text node if you pass it a string. It takes any number of arguments.

```js
el.append(document.createElement('hr'), 'I get upgraded to a text node!');
```

There's also `.prepend()` which is the opposite of `.append()`. It inserts all the elements, in-order, at the start of the element:

```js
const heading = Object.assign(document.createElement('h2', {
  textContent: 'List Of Awesome HTML Methods',
});
list.prepend(heading, `You Won't Believe How Many We Found!`);
```

## Insert Relative To Element

Every element has methods `.before()` and `.after()`. These insert new HTML nodes directly adjacent to the current node. Like the methods above, they accept any number of other elements or strings.

```js
myHeading.before(superHeading);
myHeading.after(`Here's a list of awesome stuff`, theList);
```

⚠️ There's one caveat: in our example, if `myHeading` isn't actually on the page—it's a temporary element—these methods will just fail silently without throwing an `Error`.

## Replace Self

Rather than doing a `parentNode.replaceChild` dance, we can now self-destruct an element and replace it with something new. Again, we can replace ourselves with any number of other elements or strings (even none!).

```js
const fancyItem = Object.assign(document.createElement('strong'), {
  textContent: 'fancy',
});
someFancyHeading.replaceWith('Less', fancyItem, 'heading');
someFancyHeading.replaceWith();  // although you could just use .remove 🤷
```

## Class Force Set

If you want to set the state of a class to a variable true or false, you can pass a second param to `.classList.toggle`:

```js
const someState = false;
theDiv.classList.toggle('foo', !someState);  // forces foo on
theDev.classList.toggle('bar', someState);   // forces bar off
// result e.g. <div id="theDiv" class="foo">
```

This is _probably_ well-known. But if you're explicitly not supporting IE11, it's nice to be confident that this now works. 🎉

# Done!

What have I missed? Let me know if there any other old habits you've recently discovered you can let go of.

9 👋