Create New Nodes
The DOM api has so much more in store than just moving and removing nodes. You can also create new nodes using the creation methods. We will focus on specifically the createElement
and createTextNode
methods.
createTextNode
createTextNode
is a property of the document
object that lets you create a TEXT_NODE
. It accepts a string argument which will be the data in the text node.
<body>
<div id="container"></div>
<button onClick="addTextNode()">
add text node
</button>
</body>
var addTextNode = function () {
var newTextNode = document.createTextNode('Hello World!');
document.getElementById('container').appendChild(newTextNode);
}
Try it on Repl.
createElement
createElement
is also a property of the document
object. It will let you create any HTML element by specifying an element tag name as a string. It will return the newly created element, which you can add to the DOM. We will combine it with createTextNode
to add paragraph elements to the container
div.
<!-- Add this to your HTML file -->
<button onClick="addNewParagraph()">
add new paragraph
</button>
// Add this to you JS file
var addNewParagraph = function () {
var newP = document.createElement('p');
var newTextNode = document.createTextNode('Hello World!');
newP.appendChild(newTextNode);
document.getElementById('container').appendChild(newP)
}
Try it on Repl.
innerHTML
Since we are on the subject of node creation, I want to talk about the Element property innerHTML
as well. This property lets you get and set the actual HTML code of a node. In other words, you can create or edit the child elements of a node without using the methods as demonstrated above. The limit of using innerHTML
, however, is that it is executed through a string value. Meaning it will be very difficult to iterate compared to the regular DOM api methods. At best, innerHTML
is useful for completely changing the content of a node, rather than editing a part of it.
<!-- Add this to your HTML file -->
<button onClick="setContent()">
set content
</button>
// Add this to you JS file
var setContent = function () {
var html = '<p>Hello world!</p>' +
'<p>Hello world!</p>' +
'<p>Hello world!</p>';
document.getElementById('container').innerHTML = html;
}
Try it on Repl.
There is however a security concern with this method. Since you can add pretty much any code using innerHTML
. An attacker can potentially add a script that steals client information such as usernames and passwords.
var username = 'foo';
var password = 'bar';
var stealCredentials = function () {
var html = '<script>alert(\'' + username + ' : ' + password + '\')</script>';
document.getElementById('container').innerHTML = html;
}
Try it on Repl.
If you click the button, you will notice the alert prompt never shows up. The people designing the HTML standard thought of this attack and therefore specified in the HTML5 standard that script tags inserted as a innerHTML
property does not execute.
But there are other ways to execute JavaScript in HTML.
var reallyStealCredentials = function () {
const html = "<img src='x' onerror='alert(\"" + username + " : " + password + "\")'>";
document.getElementById('container').innerHTML = html;
}
Try it on Repl.
This time, the alert popped up with the username and password values. Not good. To reduce the risk of potential breach, it is best not to use innerHTML
on data that you have no control of. Such as data added by a user, from a form or data stored in the database created by a user.
So far so good, next we will learn how to add attributes and styles to DOM elements dynamically using JavaScript.