Building HTML with Javascript

One of the things I enjoy most about HTML5, is not writing any HTML5… ever. Look, if pushed to do so… I’ll throw together an old-fashioned PHP/HTML mixed template. However, once you’ve started building DOM structures with JS, you probably will never want to go back. Writing HTML with Javascript is fun, easy and it has a number of clear advantages over writing HTML directly.

In this tutorial we’re going to examine two different ways you can build up the DOM structures (write HTML) using Javascript. One is using jQuery, the other is using straight (plain) Javascript. Gone are the days when you “needed” jQuery to manipulate the DOM. There are however still some upsides to using jQuery, and in the context of WordPress jQuery is already loaded. That likely won’t change especially in the WordPress admin any time soon, even as React becomes more commonly used in WP plugins and themes.

In Saber Commerce we started by using jQuery to build up our editors, which are the small apps contained in the WP Admin such as the Invoice Component used to manage invoices. We modeled the approach after React style components, even using a single element into which to load the entire HTML structure. However instead of React we used jQuery to handle the DOM manipulation. Later we began experimenting with constructing editor HTML using Javascript (plain JS) instead. There are a lot of similarities in the approaches, but there are some important differences as well. From experience I can say if you’ve built an entire interface out of jQuery constructed HTML, switching it over to plain JS is fairly easy and doesn’t take that much time. So if you’re more comfortable with jQuery at this point and are familiar with common jQuery functions like $.append, $.appendTo, $.html() etc., then you may want to start with a jQuery approach. One of the upsides to starting with plain JS is it’s more future-proof (if you predict a continued decline in jQuery usage) and it’s more suitable to port into React or Vue if should make that change later.

As a simple experiment to get started, we’re going to use jQuery to append a new element to the body of a document. This should work in any context, provided you have a valid HTML5 file which has a <body> tag.

jQuery( 'body' ).append( '<div>Hello Worldling</div>' );

Now let’s look at the straight javascript approach to achieve the same result of displaying a new div inside the body tag.

const el = document.createElement('div');
el.innerHTML( 'Hello Worldling' );
document.querySelector( 'body' ).appendChild( el );

As you can see from this very simple example the jQuery approach is more concise. However the plain JS approach doesn’t always lead to more code. The JS approach leads to more modularity because you build elements up line by line, for instance to add an ID to your newly created element looks like this:

const el = document.createElement('div');
el.id = 'product-283';

Similarly we can add CSS classes to elements using el.className:

const el = document.createElement('div');
el.className = 'product-item';

With jQuery we could use the same approach where we build elements in a more modular approach, but we also have the option to inject elements into the DOM in a more monolithic approach using append() or html() where we insert the entire block of code as shown below:

jQuery( '#product-item-row' ).append( '<button id="product-pay-now-1928" class="pay-now-button">Pay Now</button>' );

This doesn’t mean we can’t build up elements with jQuery, we can make the element and add attributes to it before appending.

let targetEl = jQuery( '#product-item-row' );
var button = jQuery( '<button></button>' );
button.html( 'Pay Now' );
button.attr( 'id', 'product-pay-now-1928' );
button.addClass( 'pay-now-button' );
targetEl.append( button );

In summary both jQuery and plain Javascript provide flexibility in how we construct and inject elements into the DOM. jQuery has more support for injecting full tags, though it’s worth pointing out that javascript can do this also with innerHTML. There are some considerations however when using innerHTML when you intend for events to be triggered on the injected elements. We’ll discuss that later, the short story is there is better and more immediate support for events on injected elements when they are “built” and appended with appendChild() than with innerHTML.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *