Manipulating the DOM with HTML, JavaScript, and CSS: Part 1

Aidan McBride
Nerd For Tech
Published in
8 min readFeb 21, 2021

Note: This blog has an accompanying video available at my YouTube channel here: . If you are more of an audio and visual learner, or if you just want to see the code as it is written, check it out here. Thanks!

The main purpose of front end web development is being able to style, control, and manipulate what we see on our device screens. In other words, being able to manipulate the Document Object Model, or DOM. The DOM refers to a programming interface for HTML and XML documents, representing a document as nodes and objects so that programming languages can connect to the page.

Perhaps put more simply, a Web page is a document, so when we refer to Document Object Model, we are just referring to an interface that allows us to manipulate this document with CSS, JavaScript, or whatever scripting language you choose. We will be using JavaScript to interact with and manipulate the DOM with built in methods like querySelector, getElementById, and createElement. But before we get in to manipulating the DOM, let’s set up a basic Web page with HTML so we have something to work with. Today we will be building a single page application that makes an editable ToDo list using only JavaScript, HTML, and CSS.

HTML

The base of any web page is in the HTML or hypertext markup language. This is what will build out the structure of our web page, including its elements, links to scripting languages and styles, and more. Understanding the different elements involved in an HTML document is important to the basics of web development, so create our HTML page and break down its contents.

Visual Studio has features built in that make it quick and easy to generate a boiler plate HTML document. Create a new file called index.html and inside the file on the first line, type an ‘!’. You will notice VS shows a dropdown, and if we hit enter, it will select the first option and automatically fill in the HTML file for us.

The Bones of HTML

I want to briefly discuss some of the tags within an HTML document, what they mean, and what they are used for. If you are already familiar with the basics of HTML, feel free to skip this section. If you are not, I recommend reading this to get a solid base of knowledge. We will use the default template HTML as an example:

As we can guess, the first line indicates the type of document here will be an HTML, hence DOCTYPE. Then we have our actual <html></html> tags. These enclose the entire HTML document. Next we have the head tag where we will keep any metadata, or data about the the HTML, it is not displayed. Notice the meta tags. The first sets the charset or set of characters to use. The next scales the viewport to equate to the device it is displaying on, then the title, which we can change later if we want.

We’re going to create some make a few adjustments to the HTML and add a few tags to achieve our desired goal, which is of courses to make a ToDo application. We will add a script, label, input, button, div, and unordered lists tags, as seen below:

Be sure to add classes to the tags so we can select them in our CSS later

A Note on Loading JavaScript

The script tag is used to reference JavaScript. JavaScript can be written directly in the script tag, but here we are linking an external script file. Here the ‘async’ keyword allows the JavaScript to load asynchronously, or in other words while the HTML is loading. This means that the HTML page itself will display before the JavaScript has finished executing. In this SPA, we certainly want this so we can display the outline of our page whether the script has loaded or not(in such a small app like this there will almost certainly be no difference, but it is good practice to add async). Learn more about the async keyword here.

Notice the unordered list of things to do is currently empty, that is because we are going to use DOM manipulation to add our todo items! If we want to see what our application looks like so far, we can go to the terminal and type:

open index.html

Your HTML page will be displayed in your default browser, but for the sake of this tutorial you should be using Google Chrome. So far, this is what our application looks like

The Tab at the top of the browser displays the text in the title tag within the head tag of our HTML

JavaScript

Next we will create the logic that manipulates the DOM and gives our application functionality. Create a file called index.js. Inside this file, we will start by writing some code that will allow us to interact with our HTML. WE can use a built in method called querySelector to reference HTML elements and assign them values in our JavaScript file. We call this on the document object, and pass an argument of a class or id select, determined by a ‘.’ or ‘#’ respectively. Example:

If we go back to the browser where the HTML is displayed, right click on the page and select ‘inspect’. You will see a side panel pop up with the Elements tab selected. This is Chrome’s Developer Tools, and this is a very useful tool that you will likely use the rest of your developing career. For now, we will focus on the console, so switch tabs from Elements to Console. Click on the ‘Add’ button and note the message in the console.

The developer console can be in a separate window, or within the same window as seen above

This confirms that our button we define in the HTML is linked directly to the JavaScript variable button. Congratulations, we’ve connected to the DOM! This is a great start, but now we will actually do something with this event listener, as well as create a list of todo items. First, we can created a list of todo items to start with by creating an array of strings. We will then iterate or ‘map’ over that array with JavaScript’s built in .map() method to display each one in our unordered list tag from before. In practice, the index.js file should look this:

Since our HTML reads the index.js file as it loads, thingsToDo.map will run automatically

Refreshing your browser page will now show the list we have created.

Handling Input

Now to enable our input we will set a variable equal to the selected input tag, just as with the other elements. We will also use very similar logic to that in our thingsToDo.map() function by creating a new element, setting the innerText, and appending to the list element.

There are many ways to get input values in JavaScript, but this one works fine for our app

The above logic allows us to take the value from our input box and add it to the list of to do items! Note that since we are only adding these items to the DOM element ‘list’ and, and not to our ‘thingsToDo’ array, the new ToDo items will disappear when we refresh the page. Since the JavaScript is loaded every time we refresh the page, the ‘thingsToDo’ array will always reset itself to the hardcoded list. In future blogs I will discuss persisting data, but that is out of the scope of this blog and application.

Deleting

There is one more major function that we can include in our application which is deleting a ToDo item once it has been completed. This will be the most tricky action we will perform in this project so I will cover it in depth and as clearly as possible.

Before we write any code, let’s think logically about how we can complete this. We need a way to select and individual item and choose to delete it, and the easiest way to do this is to add a ‘delete’ button to each ToDo item. In the same way we created our li or ‘list item’ element, we can create a ‘button’ element and append it to the page for each index of our thingsToDo list. By appending the new ‘button’ element we create to the ‘list item’ element, we will have a button that corresponds to each To Do item!

Adding functionality to the button is the tricky part. We will add an eventListener to the delete button that listens for the ‘click’ event, and when it is clicked it calls the built in JavaScript remove() method on the new ToDo item. The remove method simply removes the object from the DOM, allowing us to delete our unwanted To Do Item. All together our code will look like this:

Note the order of adding the button to the newToDo, then adding the newToDo to the list element

But something is not quite right with the functionality? If you add a new To Do item, you will notice there is not delete button and therefore no way to delete it. We could fix this by repeating the same logic we did inside the thingsToDo.map() function, but that would not be very DRY. One of the key concepts of programming is making sure you DRY, or Don’t Repeat Yourself. Additionally one of the key concepts of Object Oriented Programming is Abstraction, an example of which would be creating a function for some logic that repeats itself. For more information on OOP, check out one of my previous blogs on The Basics of Object Oriented Programming.

So to achieve this DRY code, we will take as much of the logic we can that will need to be repeated, and create a separate function for it. Thinking about our code logically, we can tell that in both adding a To Do item and in creating our initial list, we perform a lot of the same logic. This includes, creating an element, setting its text, and adding a delete button with functionality. What if we abstracted all that logic into its own function? We know for each situation, creating our initial list based on the hard coded array, and adding a new To Do item, we work with the same data which is simply a string. By writing a function that takes that new string, we can implement that function both at the load of our application and when we want to add a new To Do item, and only have to write the logic once!

Line 12 stays the same to convert grab the text value from the input element at the time of the button click
Finished product so far

Now we have a fully functioning To Do list, where we can add and delete items! Although it works great, it is not very pretty. In my next blog I will discuss adding some simple CSS to greatly enhance the User Interface or UI of this app, and really bring it to life.

YouTube:

GitHub Repository:

Resources:

--

--

Aidan McBride
Nerd For Tech

I am a Front End Engineer and graduate of Flat Iron coding bootcamp. Currently I work in the regulatory industry using React.