Accessing DOM elements
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
Accessing DOM elements
Element, By, and Id, but Id is not uppercase D, which often messes people up there. So what does this do? Well, we're going to call it, but not just like this. What we're going to do is create a variable and set it to the result of calling that. So if I want to grab hold of this unordered list that has an id of abc, I'm going to create a new variable called myElement and set it equal to document.getElementByID and pass in abc, the ID of the element.
And what we're doing here is we're creating a variable that is really a handle to that place in the DOM. We can then use that variable, in this case I've called it myElement, to read properties of the element. You can call methods of the element. You can even change that element. Now it's important to understand that when I do this getElementById, I'm not just making this detached copy of this single piece. Now I have a handle right into this document. I can use it to go down to the child nodes.
I can use it to go up to the parent node. It's not the detached copy of the one element; it's more like a pathway into this particular place in the DOM. Well, what if I don't have an ID on the element that I'm after, or what if I want more than one element? Well, then we have the getElementById's close relative, document.getElementsByTagName. Now notice, not getElement, but getElements, plural. What this is going to do is go through our document and give us back any of the element nodes that are anchor elements, a tags in your HTML.
Well, how does that work? So let's say we go back to the same ID of the simplified DOM here. I'm going to create a new variable called myListItems and set it equal to document.getElementsByTagName, passing in li, which means, find me all the nodes that are list item elements and return those. Well, how does it store that in one variable? It makes an array. So it makes an array called myListItems, it finds all the list items in the entire document, and then in each position of the array, in this case, there's three positions to it, we'll have a handle to that particular place in the DOM.
So we could just use the square qrackets and say myListItems(0) or myListItems(1) or myListItems(2). Now if you call the same method, getElementsByTagName and pass in a tag name that doesn't exist, so in my simplified model here I don't actually have any a href elements, what will happen is it will still return array, but the array will be empty. It won't even have a length of 1. It will have a length of 0. There's nothing there. So in this folder that I'm looking at here, I have a web page and some attached CSS and image just to give us something a bit more interesting to look at and to have a bit of content to work with.
If I were to look at the page source of this, there's nothing particularly remarkable. It's standard HTML, although down towards the bottom, I do have a link to a file called script.js just before the closing body tag. And right now there is nothing in script.js. I'm going to open that up in Aptana, though I could open up in any editor. And just to have something else to look at, I'm going to flip over and just open up this HTML file in the same editor.
I'm going to write some code to grab hold of that. So let's create a new variable. I'll call it mainTitle. Again, we must take care to make sure that the casing that we're using to grab it is exactly the same as it is in the HTML itself. The variable I didn't have to call the same name. I can call that whatever I want. And the question is, now what? Well, I have this variable which represents the object, the element object, and like all objects, like dates, like arrays, like even strings, we have things that we can ask for them.
So I'm going to write out a few console messages. And with console.log we can put a string, then a comma, and then some interesting information. So I'm going to say the message "This is an element of type" and I'm typing in my variable name, .nodeType. If you have an editor that pops up some of the auto-completion stuff, then great; otherwise, just type it in anyway.
nodeType will be a property we can access as soon as I have something back from getElementById. If you recall, I said there were three kinds of nodes we were interested in: elements, attributes, and text. Internally, they should have the nodeTypes 1, 2, and 3, so this should write us back out 1. I'll do another one here, console.log. Writing out another property called innerHTML, and as always, paying attention to the case sensitivity of this.
And the last message I'm going to write out is a message that will tell me how many child nodes I have, because when we grab hold of this element, we don't just have the element by itself; we'll also be bringing along references to any child nodes it has, or if I want to look up the way, any parent nodes as well. So every node has a childNodes property that might be empty, but I don't think it is here. It's actually an array, so it itself will have a length property. I'm just going to hit Command+S or Ctrl+S to save this, flip back over into Firefox where I actually do still have this running, and refresh the page.
Now I'm doing console messages, so I need to have Firebug opened to actually see the console. Refresh that page, and we get "This is an element of type: 1." The Inner HTML is apparently Welcome to Explore California! and this particular node has one child node. So we're programmatically reaching into the HTML here, grabbing this content, and finding information about it.
This is the innerHTML path that I was actually pulling out. I'm going to jump back in and do a little bit more code here. Now, let's use the document.getElementsByTagName. What I'm going to do here is create a new variable on Line 7 called myLinks, this will be an array, and tell this to fill it with as many anchor tags as I have. Then I'm going to write out a log message that just says myLinks.length. I'm just going to save that; for me Command+S or Ctrl+S, depending on what platform you're on. Back over into Firefox, refresh the page, and then apparently we have 19 links, 19 anchor tags on this page, and we're getting all those elements by tag name.
As soon as I have, say, an element node, I can use the same method at any level in the DOM, not just the top-level document. What does that mean? Let's say, for example, I have a slightly more complex DOM here and I run a line of code here that says getElementsByTagName. So it's document.getElementsByTagName("li"). Give me all the list items back. If I can just run this, what I'll do is I'll grab all the list items from every level of the document.
But let's say that's not what I was after. What I can do is kind of a two-stage thing here. First, I would use document.getElementById to grab that unordered list with an ID of abc, and that gives me a new variable called myFirstList. Then I'm going to call getElementsByTagName again, but instead of using the document to call it, I'm going to say myFirstList.getElementsByTagName. And what that means is it'll start at the unordered list position and look downwards and only give me back those list items.
So I'm using another element, and you'll find this all the way up and down the DOM, that you're able to reuse the same method. Once you start to get to grips with the properties that are available and the methods that are available, you can pretty much get anywhere you want.