[DOM] [Tommy MacWilliams] [Harvard University] [This is CS50.] [CS50.TV] In this video we're going to take a look at the DOM. When a browser downloads a webpage, it needs to be represented in memory somehow. The document object model, or DOM, describes how the browser represents a webpage in memory. In this video, we'll take a look at the DOM in the context of JavaScript, but DOM is a language-independent concept. For example, PHP has its own DOM implementation as well. However, DOM is frequently utilized by JavaScript since JavaScript allows us to change the contents of a webpage on the fly, and DOM allows us to access parts of a webpage. Let's take a look at an example webpage. Okay, now let's see how this page will be represented in the DOM. And every tree needs to have a root node at the top. For this document, the HTML element is the root node because it's the first element that appears. Let's add a root node to our tree. Let's take a look at the HTML document again. Notice that the body tag is nested inside of the HTML tag. This means that the body element is a child of the HTML element. We can represent this in our DOM tree by making body a leaf descending from HTML. Let's do that. We have body underneath HTML. Now we can see that body has 2 children of its own, the h1 element and the ul element. This means that we can connect both of those elements to the body element, so let's do that. We have an h1 and a ul. Finally, the ul element has 3 more children, and this will complete our DOM tree, so let's add li, li, li. This completes our DOM tree, and this is how the browser is storing your webpage. Now let's take a look at how we can traverse this tree using JavaScript. We can access this tree using a special JavaScript variable called document. One property of this document object is the body property, and this object represents the body element in our example webpage. If we wanted to get all of the children of the body element, which if you remember is that h1 tag and the ul tag, we can say document.body.childNodes. And this will give us back an array containing both the h1 element and the ul element since they're both direct children of the body. If we wanted to create a variable representing the ul element we can say vrr ul = then this code up here, and now because childNodes is simply an array we can index into it with [1] to get the second element of that array. With this new ul object we can access various properties of the element like its ID. If we say ul.id that's going to be equal to the string list because that's what we have in our HTML page. We can also get its tagName, which in this case is going to be what type of element it is, in this case, a ul. We can also get its parent or the node above it, which in this case is going to be the body element. If we say .parentNode, that's going to be the same as document.body. Of course, this ul has children of its own, so we can still say .childNodes on this element, and this array should now have length 3 because there are 3 items in our list. Finally, perhaps the most useful property is going to be .innerHTML, and this will be the actual contents of the list, which in our example page were those 3 li tags. Of course, if we have a large document, accessing elements in this manner is going to be really cumbersome because eventually we'll have to say things like document.body.childNodes bracket something .childNodes bracket something else, and it's going to get really cumbersome. Instead what we really want to do is be able to query the document, so just like we searched for things on the internet using keywords we really need some way of searching this document to succinctly get back only the elements we care about without traversing the entire tree top to bottom. Luckily, modern browsers allow us to do this with a special function called querySelectorAll, and this function takes a single argument that is a CSS selector, and it's going to return to us all of the elements that match that selector. That means you don't need to learn a whole new syntax for querying the DOM. Instead you can apply the knowledge you already know about CSS selectors. Let's take a look at some examples of querying the document. If we say querySelectorAll and pass it this string #foo that's going to give us back the element with the ID foo. You can also say document.getElementByID and pass it the string foo without that hashtag. You're going to get back the same exact object. If instead we pass the string .bar to document.querySelectorAll we're going to get back all of the elements with the class bar. We can also combine CSS selectors. If we pass in the string #foo img that's going to give us back all of the image elements that are children of the element with the ID foo. As you can see, by combining selectors we have some really powerful search capabilities. But under the hood, the DOM is really just a tree, and these selectors allow us to abstract that away to some degree because we don't always care about the entire structure of the DOM tree. That was a quick overview of the DOM, and thanks for joining us. [CS50.TV]