Chapter 4. jQuery Web Page Manipulation: Mod the DOM
Just because the page is finished loading doesn’t mean it has to keep the same structure. Back in Chapter 1, we saw how the DOM gets built as the page loads to set up the page’s structure. In this chapter, we’ll look at how to move up and down through the DOM structure and work with element hierarchy and parent/ child relationships to change the page structure on the fly using jQuery.
The Webville Eatery wants an interactive menu
Alexandra, the head chef of the Webville Eatery, has a job for you. She’s been maintaining separate web pages for different versions of her menu: the regular menu and the menu with vegetarian substitutions. She wants you to make one page that will adjust the menu for the restaurant’s vegetarian customers.
Go vegetarian
Here’s what Alexandra would like you to do.
We want a Go vegetarian button that automatically substitutes the vegetarian options on our web page menu. |
Here’s how our substitutions work:
|
P.S. If you can pull it off, we’d also like a leaf icon to show up next to the substituted vegetarian entrees. |
I had the web designer email you the files for the current menu so you can get started. |
Note
There’s no exercise for it this time around—because you’re probably already thinking it—but be sure to write down what the requirements are in your own words so you know what you’re building here.
Before we write any jQuery, let’s look at the HTML and CSS files the web designer sent us, and see if their style and structure are up to snuff.
Class up your elements
As we’ve seen in each chapter so far, we can help jQuery find elements on web pages more effectively by setting up our HTML and CSS properly. To really make our structure sing, we should add classes and IDs to our style sheet and set our HTML elements’ attributes with the appropriate classes and IDs. This makes selecting elements easier and saves you coding time later on.
For jQuery, selectors aren’t just about controlling the look and feel of your page. Selectors allow jQuery to match (or query) elements on the page, too.
Button things up
Now that you’ve got things mostly set up, let’s go back to the napkin with the head chef’s requirements. Next up, you need to build two buttons.
— We want a Go vegetarian button that automatically substitutes the right vegetarian option on our web page menu. |
— We’ll need a second button that restores the menu to its original state. |
What’s next?
That was quick! You’ve got the two buttons set up. Let’s check those items off of the napkin and move on to the stuff that the Go vegetarian button needs to do.
— We want a Go vegetarian button that automatically substitutes the right vegetarian option on our web page menu. |
— We’ll need a second button that restores the menu to its original state. |
Here’s how our substitutions work:
|
Our next task is to tackle item 1 above: match li
elements of the fish
class and remove them from the menu. We matched elements with class selectors and used remove
to take elements out of the DOM in Chapter 2.
jQuery also offers us the detach
method. detach
and remove
both take elements out of the DOM. So what’s the difference between the two methods, and which one should we use?
Swinging through the DOM tree
In Chapter 1, we learned that the DOM is built like a tree. It has a root, branches, and nodes. The JavaScript interpreter in a browser can traverse (and then manipulate) the DOM, and jQuery is especially good at it. DOM traversal simply means climbing up and down and across the DOM.
We’ve been manipulating the DOM since Chapter 1. The detach
method we just looked at is an example of DOM manipulation (i.e., we dynamically take elements out of the DOM).
But what is traversal really all about? Let’s take one section of the menu and visualize it as a DOM tree to see how traversal works.
Traversal methods let you select an element and grab other elements above, below, or beside it.
Let’s take a closer look at how you can grab those elements.
Traversal methods climb the DOM
To tell the DOM that we want to detach entrées whose menu lists contain fish, we have to reference elements by their relationship. jQuery’s traversal methods allow us to get at those element relationships.
Chain methods to climb farther
What if we want to climb higher, lower, or deeper? Strap on the chains, man! jQuery offers us method chaining. Method chaining lets us manipulate and traverse our pages in a more effective way. Here’s how it works:
Right. We can’t just detach the fish entrées and forget about them.
We’ll have to rethink our code a bit to make this work.
Variables can store elements, too
Variables must be pretty useful because we find ourselves needing them again. We’ve seen variables throughout the first three chapters, but we’ve only used them to store numbers and text strings. Wouldn’t it be convenient if JavaScript variables could store our elements too? As it turns out, they can.
The browser will hold those elements in memory temporarily. If we want to keep them to use in our program later, it’s a good idea to put them into a variable. But how do we do that?
There’s that dollar sign again...
Storing our elements is simple. We create a variable, just as we have for numbers and text strings, and set the variable (using the equals sign) to the statement that returns elements. But wouldn’t it be good to know when the variable is storing special stuff like elements (versus just numbers or text strings)? It’s common practice among jQuery coders to place a dollar sign in front of a variable that will be used to store elements returned from jQuery. That way, anyone else who looks at our code knows that we are using the variable to store stuff that we got from jQuery.
It is messy to store different elements in a variable.
That’s why jQuery uses JavaScript arrays to store elements. Let’s see what arrays are all about.
Expand your storage options with arrays
Any time we select elements from the DOM and store them in a variable, jQuery returns the data as an array. An array is simply a variable with greater storage options.
We can put stuff in and take things out of each storage slot. To put the value “15” into the third slot, we would write this:
Store elements in an array
When we select and detach the li
elements and set a variable ($f
) to the result, jQuery takes the elements the DOM returns and stores them neatly for us in a JavaScript array. When we want to put those elements back with the restore button, our job will be way less messy.
$f = $(".fish").parent().parent().detach();
jQuery takes the elements the DOM returns and stores them neatly for us in an array.
Relax
There’s a lot more to arrays.
But you don’t need to worry about that too much right now. We’ll get into a bunch more detail on arrays in Chapter 6.
Change out elements with replaceWith
The replaceWith
method allows you to replace selected element(s) with new ones. Whenever you want modify the DOM by exchanging one thing for another, you can use this handy jQuery method. Let’s say we want to dynamically change the heading level 2 element that says “Our Menu” to a heading level 1 that says “My Menu.” Here’s how you can do it using the replaceWith
method:
How can replaceWith help?
You need to match li
elements in the hamburger
class and replace them with an li
element of the portobello
class. Let’s think about that problem before we write our code.
Think ahead before using replaceWith
What’s next on the checklist?
You need to find entrées in the meat class and replace them with tofu.
Actually, we can’t use replaceWith
for this one.
replaceWith doesn’t work for every situation
The replaceWith
method works well when you have a one-to-one replacement like exchanging the hamburger
class for portbello
class.
One–to–many substitution
But the scenario of trading out elements for the next item on our checklist isn’t one for one. We have to replace many different kinds of ingredients (i.e., turkey, eggs, steak, lamb chops) with one ingredient (tofu).
Many–to–one substitution
But when we want to select tofu and replace it later, we have a problem. When we want to put the different kinds of meat back in, the DOM has forgotten about them.
We could replace tofu with just one of the types of meat, but that’s not what we wanted at all.
So we’ll need to accomplish this menu substitution in two steps:
Insert li elements of the tofu class into the DOM after the meat elements.
Detach the elements of the meat class and hold them in a variable.
Insert HTML content into the DOM
Up to this point, we’ve either removed or replaced elements in the DOM. Fortunately for us, the creators of the jQuery library gave us many ways to insert stuff into the DOM. The ones we’ll look at are before
and after
.
before
inserts content before the selected element.
after
inserts content after the selected element.
You’ve accomplished each of the steps for the Go vegetarian button:
Up next, we need to build the “Restore Menu” button. Here’s what that button needs to do.
Let’s dig right in and look at what we need to do for the first one.
We know how to use before
, but how do we specify the first child?
Use filter methods to narrow your selections (Part 1)
Fortunately, jQuery provides filtering methods that let us narrow our selection for problems like finding the first child. Let’s look at six of them (three on this page, three on the next).
|
|
|
The | The | The |
Let’s look at one item from our menu to see how these methods work:
Use filter methods to narrow your selections (Part 2)
Now let’s check out the slice
, filter
, and not
methods, and how they work.
|
|
|
The | The | The |
The filter
and not
methods let us use selectors to create a subset from the matched set using selectors as arguments of their methods.
Which of these methods will help you specify the first child on the menu?
Bring the burger back
So far for the “Restore Menu” requirement, we’ve got one item down, two to go:
Our next checklist item seems a bit like déjà vu, doesn’t it? All we really need to do is reverse what we did for the original substitution. Why? Because we’re dealing with a one-to-one substitution, and we love one-to-one substitutions because they’re logically simple.
Where’s the beef (er...meat)?
We’re down to our last item for the “Restore Menu” button:
What did we do with those li.meat
elements again? Let’s review:
We put li.tofu
elements into the DOM after the meat
elements.
$(".meat").after("<li class='tofu'><em>Tofu</em></li>");
Then, we detached the li.meat
elements but held on to them by saving them into $m
.
$m = $(".meat").detach();
So where are those elements, and how do we bring them back?
A meaty array
Remember that whenever we store jQuery elements, we give the variable a dollar sign to signify that the variable we’re using has a special kind of storage. In this case, it’s a jQuery array, and here’s how the elements in $m
are stored:
The each method loops through arrays
In Chapter 3, you saw how to use the each
method to loop through elements. We can use it again here to loop through all the meat
elements in the $m
array and put them back where they were. But to do that, we’ll need to check out a bit more about how the each
method works.
The each method is like an assembly-line machine for your elements.
That’s it...right?
You did everything required for the “Restore Menu” button. Let’s update our files and call this project done.
P.S. If you can pull it off, we’d also like a leaf icon to show up next to the substituted vegetarian entrées. |
Oops, you’re right.
Luckily, the web designer already put the veg_leaf
class in the my_style.css file. Let’s have a look at it.
Your jQuery Toolbox
You’ve got Chapter 4 under your belt and now you’ve added DOM manipulation and traversal, arrays, and filters to your toolbox.
DOM manipulation
You can add to, replace, and remove things from the DOM at will:
detach
remove
replaceWith
before
after
Arrays
jQuery arrays store all kinds of things, including elements, so you can access them later.
Just like with variables, put a $ in front of your array to signify that it is storing special jQuery goodies.
Get Head First jQuery now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.