Creating DOM elements
Video: Creating DOM elementsWhile you could use the innerHTML method to just write out a bunch of HTML and dump it into a position in your document, it's not a clean way to do it, and it's easy to make a mistake. The best way is to start manually creating and inserting individual DOM element nodes into your document, and this is a very powerful technique to learn. It lets you change your page on the fly and to do it, there's always two steps. One, you create the element. You say I want to create a paragraph or a heading or a list item or an anchor tag.
Viewers: in countries Watching now:
- Creating variables, functions, and loops
- Writing conditional code
- Sending messages to the console
- Working with different variable types and objects
- Creating and changing DOM objects
- Event handling
- Working with timers
- Building smarter forms
- Using regular expressions
Creating DOM elements
While you could use the innerHTML method to just write out a bunch of HTML and dump it into a position in your document, it's not a clean way to do it, and it's easy to make a mistake. The best way is to start manually creating and inserting individual DOM element nodes into your document, and this is a very powerful technique to learn. It lets you change your page on the fly and to do it, there's always two steps. One, you create the element. You say I want to create a paragraph or a heading or a list item or an anchor tag.
And step two is you then add that newly created element to the right place in the DOM, the right place in the document. So here's an example. If I imagine I've got a very simple HTML page representing here as a set of DOM nodes, I can see that my body consists of three things: an h1 heading, a paragraph, and an unordered list with an id of abc. That unordered list has three list items underneath it. And I can imagine I've already used getElementById to create a variable called myElement that points to that unordered list.
That will be important in a second. So if I want to add a new list item to this point in the DOM, a new list item to the unordered list, what I have to do is first, step one, create the element. And instead of using document.getElementById, we use document.createElement and I pass in a string that says what kind of element. In this case, it's an li. If I wanted a paragraph, it would be a p; if I wanted an anchor tag, it would be an a; and so on. Now that creates it, but it creates it kind of out there in space.
Well, I could, if I wanted, use innerHTML and just actually set the text of the list item. And that would work, but there is a preferable way to do it as well, or a more exact way, which is that after we've created the element itself, we then create a text node. Remember that the element and the text they contain are actually different. So if I've got that variable myNewElement that points to that list item, what I'm then going to do is use the createTextNode method, which creates this text node. Very similar to creating an element, it's out there in space, not attached to anything.
So this is the place that I want to create new DOM elements and add them right here. So the way to do it, if I come over to my script.js file, I've got some code that already exists. I'm just going to uncomment it. And I'm actually going to do two things here: I'm going to create an h1 element, and then I'm going to create a p, or paragraph, element. So lines 2 and 3 we actually create new variables creating those elements, but they're just existing out there in space. They actually aren't part of the page yet. Well, not only that, they don't have any content.
So if I want to do the slightly easier way but not as exact as possible, we could call the innerHTML on both of these new variables. So newHeading, which I just created, set its innerHTML to "Did You Know?" And the newParagraph, which I just created, set its innerHTML to "California produces over 17 million gallons of wine each year." So we have our elements, we have some text added to them, but they're still not part of the page. And in fact, right down here on Line 17 and 18 I'm just going to uncomment these lines because this is how we add them to the page.
If you remember, the div that I wanted to add them to is called trivia. So we call document.getElementById ("trivia").appendChild(newHeading), we're adding the h1, and then we call the whole thing again, and then we say we'll now append another child, which is the paragraph. So if I save this and I just open that up in the browser again, what we'll find is that that part of the page that was blank now has this content that's been dynamically added. And because it's using the same CSS rules as the rest of the page, I have a formatted headline with the underline and I have the correct font showing up.
But let's just talk about the more exact way of adding text. We can use innerHTML, but the alternative way is going to be below here. It's going to require two more lines of code, but it is a bit more exact. And we do it similar to creating the elements themselves. We actually create new text nodes. So on Line 10, I'm creating a variable called h1Text and calling document.createTextNode and giving it a little bit of text to initialize itself, and then the same thing on Line 11 for the paragraph.
But because you create text nodes just like elements that are just existing disconnected out in space, what I'm then doing is on Line 13 and 14 I'm associating those new text nodes with the new h1 and the new paragraph that I created on Line 2 and 3. And I'm leaving line 17 and 18 exactly as they are because we still need to add the new heading and new paragraph to our DOM. Save that, jump back over into the browser, and if I refresh this, we should see absolutely no changes at all.
Again, you can make your own decisions about which method to use. Creating text nodes separately does mean typically writing a little bit more code, but it is a more exact and more specific way to do it. So while the process is always going to be a step one, create the element, step two, add it to the DOM, there is an alternative to appendChild, although that is the most common one. Instead of just pointing to the parent element and saying appendChild, we also have the choice of insertBefore. So if you want a bit more flexibility about where our new element is inserted into the DOM, we can use this one as well.
Let me show an example here. So taking the same idea of that DOM tree that we had before, appendChild will always add that new list item right at the end. It will always add it, as in this case, the fourth list item. But what if I didn't want that? Well, step one is still the same: create the element. We're creating it there out in space. Now the second step here is I need to grab hold of a variable that points to, in this case, let's say the second list item, and I'm going to do this by calling getElementsByTagName, because that second list item doesn't have an ID.
So I'm first calling myElement.getElementsByTagName, saying I want to find all the list under the unordered list. And then I'm using the square brackets and saying number one, which if you remember, we're going to use zero-based arrays, so the first one would be at position 0, the second one at position 1, the third one at position 2. So I now have a variable, secondItem, that points to the second list item. And what I can do is use the other way of adding to the DOM.
Instead of appendChild, I call myElement.insertBefore and the two pieces of information I give it is what's the new element and what's the element you want to insert it before, in this case, secondItem, at which point it will reshuffle that arrangement and insert my new list item into that very specific point in the DOM. So most of the time, you'll be using appendChild, but insertBefore can come in very handy as well.