📖 Deeper dive reading:
- MDN Introduction to the DOM
- W3C DOM specification - This official specification is only for reference
The Document Object Model (DOM) is an object representation of the HTML elements that the browser uses to render the display. The browser also exposes the DOM to external code so that you can write programs that dynamically manipulate the HTML.
The browser provides access to the DOM through a global variable name document that points to the root element of the DOM. If you open the browser's debugger console window and type the variable name document you will see the DOM for the document the browser is currently rendering.
> document
<html lang="en">
<body>
<p>text1 <span>text2</span></p>
<p>text3</p>
</body>
</html>p {
color: red;
}For everything in an HTML document there is a node in the DOM. This includes elements, attributes, text, comments, and whitespace. All of these nodes form a big tree, with the document node at the top.
Every element in an HTML document implements the DOM Element interface, which is derived from the DOM Node interface. The DOM Element Interface provides the means for iterating child elements, accessing the parent element, and manipulating the element's attributes. From your JavaScript code, you can start with the document variable and walk through every element in the tree.
function displayElement(el) {
console.log(el.tagName);
for (const child of el.children) {
displayElement(child);
}
}
displayElement(document);You can provide a CSS selector to the querySelectorAll function in order to select elements from the document. The textContent property contains all of the element's text. You can even access a textual representation of an element's HTML content with the innerHTML property.
const listElements = document.querySelectorAll('p');
for (const el of listElements) {
console.log(el.textContent);
}The DOM supports the ability to insert, modify, or delete the elements in the DOM. To create a new element you first create the element on the DOM document. You then insert the new element into the DOM tree by appending it to an existing element in the tree.
function insertChild(parentSelector, text) {
const newChild = document.createElement('div');
newChild.textContent = text;
const parentElement = document.querySelector(parentSelector);
parentElement.appendChild(newChild);
}
insertChild('#courses', 'new course');To delete elements call the removeChild function on the parent element.
function deleteElement(elementSelector) {
const el = document.querySelector(elementSelector);
el.parentElement.removeChild(el);
}
deleteElement('#courses div');The DOM also allows you to inject entire blocks of HTML into an element. The following code finds the first div element in the DOM and replaces all the HTML it contains.
const el = document.querySelector('div');
el.innerHTML = '<div class="injected"><b>Hello</b>!</div>';However, directly injecting HTML as a block of text is a common attack vector for hackers. If an untrusted party can inject JavaScript anywhere in your application then that JavaScript can represent itself as the current user of the application. The attacker can then make requests for sensitive data, monitor activity, and steal credentials. The example below shows how the img element can be used to launch an attack as soon as the page is loaded.
<img src="bogus.png" onerror="console.log('All your base are belong to us')" />If you are injecting HTML, make sure that it cannot be manipulated by a user. Common injection paths include HTML input controls, URL parameters, and HTTP headers. Either sanitize any HTML that contains variables, or simply use DOM manipulation functions instead of using innerHTML.
All DOM elements support the ability to attach a function that gets called when an event occurs on the element. These functions are called event listeners. Here is an example of an event listener that gets called when an element gets clicked.
const submitDataEl = document.querySelector('#submitData');
submitDataEl.addEventListener('click', function (event) {
console.log(event.type);
});There are lots of possible events that you can add a listener to. This includes things like mouse, keyboard, scrolling, animation, video, audio, WebSocket, and clipboard events. You can see the full list on MDN. Here are a few of the more commonly used events.
| Event Category | Description |
|---|---|
| Clipboard | Cut, copied, pasted |
| Focus | An element gets focus |
| Keyboard | Keys are pressed |
| Mouse | Click events |
| Text selection | When text is selected |
You can also add event listeners directly in the HTML. For example, here is a onclick handler that is attached to a button.
<button onclick='alert("clicked")'>click me</button>This CodePen dynamically manipulates the DOM using JavaScript. Create a fork of the pen and take some time to experiment with it. Then complete the following:
-
Add a new table that represents the seven peaks of Utah County.
- name: "Timpanogos", height: 11750, quality: 4.8
- name: "Santaquin", height: 10687, quality: 3.8
- name: "Lone Peak", height: 11253, quality: 5
- name: "Provo Peak", height: 11068, quality: 4.1
- name: "Cascade", height: 10908, quality: 3.2
- name: "Nebo", height: 11928, quality: 4.8
- name: "Spanish Fork", height: 10192, quality: 3.4
-
Sort the table when a header is clicked on
If your section of this course requires that you submit assignments for grading: Submit your CodePen URL to the Canvas assignment.
Don't forget to update your GitHub startup repository notes.md with all of the things you learned and want to remember.
If you get stuck here is a possible solution.
