New terms from treehouse – jQuery Basics Part 2 – Mobile Drop Down, Password Confirmation and Drawing App Projects

Creating a Mobile Drop Down Menu

We have a site with a top nav that doesn’t look good on mobile. Highlighted to show some of the links go missing.

Screen Shot 2014-09-29 at 1.40.33 PM

Here is our current problem/solution and psuedocode gameplan:

Screen Shot 2014-09-29 at 1.52.44 PM

We’ll start by created a detached (aka disembodied) element for the select element. Then we’ll append it to the menu div, and check to see if it worked (it did).

Screen Shot 2014-09-29 at 1.57.49 PMScreen Shot 2014-09-29 at 1.57.54 PM

Now we need to cycle over the menu links, so we’ll select those with “#menu a”. This is better than div a because it’s more specific. To cycle over them, we should look under the traverse section, and choose the each() method, which let’s us iterate over a matched object, executing a function for each matched element.

We’ll start with a disembodied element $anchor which simply refers to the link, the create an option element using one as well, calling it $option. We’ll then set the option’s text to that of the link’s using the text() method twice, once to set and once to get: $option.text($anchor.text());. Then, we’ll add these new options to the select element using  $select.append($option);. Finally, we’ll set the value attribute of the option element using the val() method listed under attributes. So we’ll write $option.val($anchor.attr(“href”);, which is saying, set the value attribute of option to the value of the href attribute on the anchor element.

Screen Shot 2014-09-29 at 2.25.44 PM Screen Shot 2014-09-29 at 2.26.10 PM

Now, we’ll create a button and append it to the #menu div using the same disembodied element way as before.

Screen Shot 2014-09-29 at 2.29.58 PM

Next we’ll bind a click handler to that button using ${});. Now we need to make it go to the select’s location when clicked. We want to use the value of the value attribute for the $select objects, so we can use the val() method again, this time as a getter because we’re not passing in any parameters. We’ll then use window.location, which is how Javascript let’s you change the windows location, and set it to that.

Screen Shot 2014-09-29 at 2.36.42 PM

Now, when you choose the option from the drop down and click the Go button on the right, it takes you to the selected page.

Screen Shot 2014-09-29 at 2.37.03 PM

Password confirmation project

Here we have some pop ups for when you put in your password wrong that we only want to show during certain conditions. Here’s that and the pseudocode gameplan:

Screen Shot 2014-09-30 at 4.13.39 PM

We start by hiding the spans.

Screen Shot 2014-09-30 at 4.16.26 PM

Now we need to select the password input when someone is writing in it. We’ll select it using the id on the input element, “password”. Then we’ll use the focus() method, under Events > Form Events, which occurs when you click on an input field, giving it focus. It accepts a handler, which is an anonymous or named function.

Screen Shot 2014-09-30 at 4.22.04 PM

We’ll then use the val() method again, which works for select, textarea and input form elements. It returns a string, and strings in JS have a property called .length, which returns the length of the string, so we’ll put that at the end of it. We’ll then set that > 8 and we now have our parameter for our if/else block.

Screen Shot 2014-09-30 at 4.26.24 PM

We now need to traverse the DOM a bit, because we’re trying to show/hide the span that comes after the input.

Screen Shot 2014-09-30 at 4.28.05 PM

The next() method under traversing the DOM let’s us do that. We add this in to show and hide it.

Screen Shot 2014-09-30 at 4.31.57 PM

But this doesn’t work. Even if we write 9 characters, it doesn’t disappear until we give it focus again. What we really need is a method that binds the event (what triggers the function) handler (its function) to when you’re done with your keypress: keyup(). We’ll add this to the end of our current thing, but rather than do the same code twice for hiding and showing, we’ll just make that into our own named method for later use, calling is passwordEvent. Now it works!

Screen Shot 2014-09-30 at 4.38.42 PM

Now to do the confirmation password, which has an id of confirm_password. Since the solution here will probably be similar, we’ll start by getting another function ready, confirmPasswordEvent. We need the event to happen on confirmation input, so we’ll set that up the same way too.

Screen Shot 2014-09-30 at 4.58.42 PM

Now we need to find out if the confirm password is equal to the first password.

Screen Shot 2014-09-30 at 5.02.28 PM

But this is starting to get a bit messy, so we’ll make some variables for them, which allow us to use them instead and also replace all the $(this)’s from the last function.

Screen Shot 2014-09-30 at 5.05.05 PM

We now need to show and hide the hint, so we can do just what we did before with next() and hide/show().

Screen Shot 2014-09-30 at 5.08.04 PM

But what if our passwords match, then we go back and change the first password? The confirm hint should show up again because they don’t match, but it won’t unless we focus on it or keyup. We can do this by calling the confirm password events on the first password object as well.

Screen Shot 2014-09-30 at 5.13.29 PM

A good thing to note – we can use focus() twice with different event handlers and they don’t mess with each other. So when we focus on it, it’s doing both focus() methods, not just the first one. It’s good we made them variables as well, because using $(this) would have messed this up.

Time to perfect this by making the submit button invalid if the password isn’t long enough or if they don’t match. So, we want to add the disabled boolean attribute to the submit input element.

We’ll start by making two functions, one to check if the first is 8 characters and the second to check if they’re matching. For the first one, we can actually replace the first part of the passwordEvent one in the if block, since it will be returning that and is the same thing.

Screen Shot 2014-09-30 at 5.37.09 PM

What’s nice is that if there are other conditions need later for the password (like 1 cap 1 number, etc), we can just add them to the isPasswordValid() function now.

We’ll do the same thing for whether they’re matching.

Screen Shot 2014-09-30 at 5.39.31 PM

Now we’ll make a function for whether it can submit or not. Remember, return with something after will return true or false.

Screen Shot 2014-09-30 at 5.42.03 PM

Now we need a function to enable or disable the submit event. An exclamation point means “not”, so !true = false and !false = true. In the function, we’re selecting the submit button, the we’re changing the “disabled” property based on whether the canSubmit() returns true or false. However, right now if it’s true, which means the button should be good to submit, it would return true and add the disabled property. We want the opposite, so we put in !canSubmit(), which flips those values.

Screen Shot 2014-09-30 at 5.49.00 PM

Now we can add that to our previous code, with keyup() at the end of each.

Screen Shot 2014-09-30 at 5.51.52 PM

However, if we just click submit as soon as the page loads, all this doesn’t work because it’s dependent on a keyup event in the password or confirm inputs. So, we need to execute it when the page loads. So, we simply put this at the bottom.

Screen Shot 2014-09-30 at 5.56.05 PM

Simple drawing application project

We should always aim for our projects to work without JS, this is called graceful degradation. 5 of the 6 projects we’ve done here do that, except for this one, but we don’t really have a choice as there’s no other way for us to get it working. Here’s the problem/solution and pseudocode game plan:

Screen Shot 2014-10-01 at 3.11.12 PM

First is to get the color selector working. We’ll use the click() method. We should also create a variable for the .selected color, as we’ll likely be using that a bit for other stuff. We select it using the .selected selector, then we need its color property so we’ll use the .css() method.

Screen Shot 2014-10-01 at 3.18.59 PM

We’ll probably want to cache the current color, so we can copy that code and put it in the function, using (this) instead for the selected color. Now, to deselect the sibling elements, we’ll first use this, for the thing we clicked, followed by the .sibling() method, which selects its sibling elements, then finally we can use the .removeClass() method to remove the specified .selected class from them.

Screen Shot 2014-10-01 at 3.25.07 PM

Then, to add a class we simply use this and the addClass() method, and we’re good to go.

Screen Shot 2014-10-01 at 3.30.25 PM

Now to make the new color button work. We want to hide or show the color selector when you click the button, based on whether it’s hiding or showing at that time. The show and hide methods aren’t the best option for this, you should use the toggle() method. With no parameters, it simply toggles the visibility of elements. So, we’ll set up a click method on the button, and the toggle method on the colorSelect div.

Screen Shot 2014-10-01 at 4.02.37 PM

Now to update the color span when the sliders change. We’ll start by creating our own method called changeColor, which will change the background-color css property of our selected #newColor span. Then we need to select the range inputs, the sliders, which we can do with attribute selectors. We then use the on() method that says, on an input (which is when you move the slider in this case), it triggers the handler, which in this case is our changeColor function.

Now, in our changeColor() method, we created a variable for each of the color sliders, that takes their value, which is where the slider is at. We then did some math with the css() method that added the three variables together to give us an rbg value, which is what is set as the background color for the #newColor span. It starts as black when we click the new color button because all the sliders are at 0, making it black.

Screen Shot 2014-10-01 at 4.22.20 PM

Now we need it to actually add the new color when you click the Add color button. We’ll start with the click method on the selected button, then create a disembodied list item element. We then want to alter that new color’s background color using the css() method. For the value we’ll use the $(“#newColor”).css(“background-color”) created from the previous method above. We’ll then append() it to the ul list in the div with the.controls class. We’ll then try and make it select it with a click() method.

Screen Shot 2014-10-01 at 5.32.12 PM

Issue – the color gets added (yay!) but doesn’t get selected. The issue is because the click listener we created earlier that switched the selected color on picking one, when the page loads, it binds the click handler to the existing ones, and ignores any new list items. We need a method that will bind when the page loads but also for any future things elements added. The on() method let’s us do that. First we set what happens, the click, then the child element we want it to happen to, the “li”, then we set the function that runs when that happens.

Screen Shot 2014-10-01 at 5.40.29 PM

Ok, finally we get to make the pencil draw stuff. This works via the HTML5 canvas element. First we select the canvas element using jQuery, then we’re actually going to select the canvas itself instead of the jQuery representation of the canvas, and we do this by writing [0] after it. This is actually the same as writing document.getElementByTagName(“canvas”)[0], only easier to write/read. The reason we do this is because the actual element has a special method we can call on that element, which is to get its context – .getContext().

Context in 2d and 3d graphics is just a way for the computer to know where to draw. We’ll set the value to “2d”. We’ll then save this as a variable. Online you may see it named ctx, which is short for context. Finally we’ll move it to the top so we can cache it as a variable when the page loads.

Screen Shot 2014-10-01 at 5.48.47 PM

Now for the drawing code. We’ll start with the context variable, then the beginPath() method, which is saying in the context we want to start a path. We then use moveTo() to say the distance we want it to move on the x and y coordinates, in px. This will be our starting point. Then we use lineTo() to say where the line will go. If we write 20, 10, it will move on the x axis ten px. This is the ending point. Finally, we use .stroke(), and get this:

Screen Shot 2014-10-01 at 5.53.48 PM Screen Shot 2014-10-01 at 5.53.44 PM

To draw a square, we just add more lineTo’s. For the last line, we can use a method called closePath(), which will close things up for you.

Screen Shot 2014-10-01 at 5.56.21 PM Screen Shot 2014-10-01 at 5.55.09 PM

Now to make the pencil do this. When you draw, you don’t just click, you click and hold the mouse down, the let go, so we’ll use the mousedown()mousemove()  and mouseup() methods, in that order. First we’ll select the canvas and cache it as a variable, putting it at the top of the page.

Screen Shot 2014-10-01 at 6.17.50 PM

We’ll apply the mousedown() method to the $canvas object. Just like keyboard click events, there is an event object that can be passed into the handler. When we click down with a mousedown event, it gives us the coordinates. To save this, we’ll first create another global variable, lastEvent. Then in the mousedown() method we’ll pass in e and set lastEvent equal to that. When we check it in the console, we can see a bunch of properties for it now, based on where we clicked. This includes the offset x and y, which we’ll use in our drawing code.

Screen Shot 2014-10-01 at 6.20.16 PM

Screen Shot 2014-10-01 at 6.19.34 PM Screen Shot 2014-10-01 at 6.18.51 PM

Now we need to write what happens when the mouse is moved while being held down. When can chain the mousemove() method onto the one we just wrote, and will pass in e again. We can use the same code we used before with some tweaks. We’ll leave in beginPath, and for moveTo, which remember is the offset, well pass in the lastEvent variable with its properties for the x and y offsets. Now for the lineTo, which draws the line, we do e.offsetX and Y. We can then remove the other lineTo’s and the closePath as they’re not needed.

With the current code, we get this:

Screen Shot 2014-10-01 at 6.27.08 PM Screen Shot 2014-10-01 at 6.27.01 PM

So we’re still drawing even when the mouse is up. What we need to do is update the last event so it stops drawing on mouseUp(). First we’ll set lastEvent to e again, which makes it at least follow the cursor. We want to store if a mouseDown has occurred, so we’ll create a variable for that, and set it to false. Then in our code below, we’ll set it to true. We’ll then use this to make an if block for the drawing code, which will only be true (and therefore running) when the mouse is down.

Screen Shot 2014-10-01 at 6.30.37 PM Screen Shot 2014-10-01 at 6.33.05 PM

Now we get to add on the mouseup() method. We’ll add it in and make it so that it causes the mouseDown variable to be set to false, stopping the drawing.

Screen Shot 2014-10-01 at 6.36.10 PM

Now to make it actually use the selected color. We do this with the strokeStyle property for context, and setting it to our color variable from before.

Screen Shot 2014-10-01 at 6.40.09 PM

One last issue – when you draw outside the canvas and come back in, a line appears.

Screen Shot 2014-10-01 at 6.44.45 PM

The mouseleave() method binds an event handler to when the mouse leaves a an element. We’ll the make the function simply trigger the mouseup() method from above, and we’re good.

Screen Shot 2014-10-01 at 6.48.48 PM

Finally done, woooooo!

New terms from treehouse – jQuery Basics Part 1 – Basics and Spoilers/Lightbox Projects

jQuery is like CSS in that it takes the JS out of the markup and let’s you modify it in another place. It also uses the same selectors as CSS.

Unobtrusive (as in, not getting in the way of the user) JS is all about putting the user first, and making sure the site works regardless of their connection, browser or device. This is the key to user experience.

What is jQuery? A javascript library, which is just a collection of JS code. You write in in a separate .js file. You can use jQuery as a function, which if you remember needs to be followed by parentheses. Simply write in the CSS selector of the element you want to manipulate. In this case we want to hide the “It’s a trap” text then make it appear. Since we want to select a class, we write it with a period first like we would in CSS, then surround it in quotes.

Screen Shot 2014-09-24 at 5.26.16 PM

Screen Shot 2014-09-24 at 5.31.50 PM

You can then call methods on them to modify their behavior. In this case we want to hide it, but where would we look to learn how to do that? You can check out the documentation site.  Use the search box in the top right to look for stuff. Here we want to use .hide(). Notice how it gives code examples at the bottom.

Screen Shot 2014-09-24 at 5.36.43 PM

To get it to show, we’ll use the .show() method. However, if we just add that it won’t give us what we want, the “It’s a trap” will show instantly. So, we pass in the string “slow” as a parameter, like we saw in the documentation.

Screen Shot 2014-09-24 at 5.44.27 PM

Now, instead of having to write jQuery all the time, you can instead use a $.

Screen Shot 2014-09-24 at 5.45.33 PM

jQuery has method chaining, which allows you to reduce redundancy in your code. You can add methods after each other to affect the same selected elements. This works because many jQuery methods return the element they were selecting. So, hide() returns the .warning elements.

Screen Shot 2014-09-24 at 5.48.46 PM


The Document Object Model is how the browser interprets the html files. Aka the DOM tree.

Screen Shot 2014-09-24 at 5.51.58 PM

HTML elements can be manipulated, added and removed using JS. In dev tools, you can pull the document object, which everything hangs off of. Screen Shot 2014-09-24 at 5.55.21 PM

Let’s say we wanted all the children elements of the head element. Simply write document.head.children

Screen Shot 2014-09-24 at 5.57.25 PMYou can access this array of elements just like any array, by passing in the index of the element you want. If we want the first p element in the body, we’d write document.body.children[0]. Remember, you can pull up what you’ve previously written by using the up key.

Screen Shot 2014-09-24 at 6.00.17 PM

However, this it a brittle way to program, we don’t know if the order of the elements in the html document will change in the future.

Moving from on element to another is called traversal, or, traversing the DOM.

The method getElementByClassName is a much better option. Here we’ll select the element with the .warning class: document.getElementsByClassName(“warning”). Note that in the string a period wasn’t used, because we’re already saying we want a class name with the method.

Screen Shot 2014-09-24 at 6.05.07 PM

jQuery makes this way easier, and also will make it work with all browsers.

Screen Shot 2014-09-24 at 6.07.19 PM

jQuery Documentation

There are different kinds of methods based on what you’re looking to do.

Screen Shot 2014-09-24 at 6.44.42 PMScreen Shot 2014-09-24 at 6.45.21 PMScreen Shot 2014-09-24 at 6.45.50 PM

Now, we’ll go over the different categories listed on the left hand side in the documentation.

The attributes category lets you change and modify the attributes of elements, like if you need to change the href attribute for a link. You can also use this to add/remove classes, or see if an element has a class.

The CSS category lets you change and read the style properties. You’ll find that the add/remove class methods are here as well, sometimes they will be in multiple categories.

The dimensions category lets you check an elements heights, widths, etc, with or without the padding and margins. This is manipulation.

The effects category is manipulation over time, like an animation, showing, hiding, fading in/out, etc.

The events category is basically for when a user interacts with a thing, like the keyboard in a form, scrolling, resizing a window, etc, then doing something when that occurs. Has sub categories for each of these. Can be triggered by user or the computer.

The offset category is similar to dimensions, is used to figure out the offset of an element, like from the top or the left of a parent element, how far it’s been scrolled right of left. Handy for triggering an event for the browser to scroll to the top or bottom of a page.

The traversing category includes all the methods to move around the document and manipulate it. Like getting the children of an element, or elements with a certain class.

The selectors category talks about the CSS selectors that can be used for jQuery. There are even special jQuery selectors can only be used with it and not CSS.

Ways to include jQuery in a project

You can download it from But, what most people do is host it on a CDN, a Content Delivery Network, which serve jQuery all over the world. The nice thing is if the user has already been on a page that has this, it’s been cached in their browser so they don’t have to download it again. Put the CDN link above your link to your .js file.

Screen Shot 2014-09-24 at 7.08.10 PM

However, when we try to execute the function in our .js file, it doesn’t work.

Screen Shot 2014-09-24 at 7.10.28 PM

In the documentation, under Events > Document loading, we find the ready() method, used for executing a function when the DOM is fully loaded. Note the other two hear are marked as depreciated and should be ignored. Looks like there’s three ways to do this.

Screen Shot 2014-09-24 at 7.14.05 PM

We can select the document itself and run it with this method, we’ll ignore the second method, or simply run the function when the page is ready.

It’s worth noting, that “handler” is explained above, and basically just means the function you want to run.

Screen Shot 2014-09-24 at 7.14.11 PM

We’ll try the first method. Note that we don’t use parentheses to call the function in this case, as we want jQuery to do that once the page is loaded.

Screen Shot 2014-09-24 at 7.17.44 PM

Now, remember that we can also declare functions using a variable. So instead of this,

Screen Shot 2014-09-24 at 7.18.44 PM

we do this, and it still will work.

Screen Shot 2014-09-24 at 7.19.31 PM

Now, a lot of times people will use functions without a name, aka an anonymous function. We can actually pass the function itself into the ready method. The example below works as well.

Screen Shot 2014-09-24 at 7.21.58 PM

If you remember, the third way that you can do this is by simply passing the handler into the jQuery method, which is $().

Screen Shot 2014-09-24 at 7.23.35 PM

Now, in our original example last lesson we didn’t do that, because we included our jQuery at the bottom of the mark up.

Screen Shot 2014-09-24 at 7.25.02 PM

By doing this, the code will still work, but now we don’t need to wait for that .ready event to be triggered by the DOM. Because we’re including the JS at the bottom of the page, we can assume that the DOM has already loaded. We can now cut out those parts of the code.

Screen Shot 2014-09-24 at 7.27.47 PM

This way of including the JS at the bottom of the page is a best practice, because it speeds up the user’s experience. It’s a bit faster, and lets your content and images load before your JS files do.

Spoiler revealer project

Screen Shot 2014-09-25 at 2.17.30 PM

Preparation is where is sleuth out what the problem is (the first two lines below). In the plan stage, we’ll write some pseudocode, which is high level, informal code that describes what we’re looking to do.

Screen Shot 2014-09-25 at 2.26.23 PM

We’ll start by selecting the span containing the spoiler. Note how we were able to use a descendent selector, just like in CSS.

Screen Shot 2014-09-25 at 2.35.08 PMScreen Shot 2014-09-25 at 2.35.14 PM

Next, we need to add a button. To do that we’ll use append(), listed under Manipulation, which adds content to the end of the specified element. The parameters is accepts include html, so we’ll make it take a button. NOTE: They already had styling in place for the button.

Screen Shot 2014-09-25 at 2.41.31 PM

Screen Shot 2014-09-25 at 2.41.49 PM

Now, we want to hide the button and show the spoiler on a mouse click. Under Event > Mouse Events we find the .click() method. To remove the button, we’ll use the .remove() method under the manipulation > DOM removal section.

Screen Shot 2014-09-25 at 3.05.57 PM

Now, will the remove method we were able to use “this”, rather than having to write the selector for button elements. The nice part about this is that it refers to specific button that’s being clicked, and will affect just that button, rather than all buttons on the page. If we were to instead use the button selector, all buttons on the page would be removed whenever we clicked any button.

REMEMBER, the selector you put in the parentheses after the $ is what is going to be affected by the method after. So $(“.spoiler span”).show(); will show any span element within one with the spoiler class.

Now, to perfect our project. Let’s put in another spoiler. Issue – when we click one of the buttons, both spoilers get revealed.

Screen Shot 2014-09-25 at 3.10.14 PM

In our current code, we’re selecting all spans within a spoiler class element, which is not good, we only want to affect the span for the button we clicked. We want to select the previous element to the button, which we can do with the prev() method, under the traversing the DOM section. It selects the immediately preceding sibling element.

Screen Shot 2014-09-25 at 3.15.21 PM Screen Shot 2014-09-25 at 3.15.17 PM

Now, jQuery methods return things, which I guess means the things that will be selected. So with $(“.spoiler span”).hide();, it’s returning what was selected in those first parentheses. However, with something like the  $(this).prev().show(); used above, .prev() is actually returning the sibling of button (which were using this to refer to), rather than button itself. That sibling is then affected by the .show() method.

Creating a Simple Lightbox

Issue is that when you click on one of the images it takes you to a dead end, which is a poor UX. Solution: make a lightbox with jQuery. Here’s that with the psuedocode for our plan:

Screen Shot 2014-09-26 at 2.34.13 PM

First, we need to capture the click. The best way to do this, with keeping future scenarios in mind, would be to create an id for the unordered list. That way, if there are non image links added to the site later they won’t be affected. To do so, we then simply write $(“#imageGallery a”).click();

To add to that, we want to select the info in the href attribute for those links. We can use this to make sure we’re getting it from the link that’s just been clicked, along with the attr() method, which is unsurprisingly listed under the attribute section. We can simply pass in a string for the name of the attribute we want. We can then store that in a variable, which we’ll name href, then use a console.log with that variable to display it in the console. We should now see what was listed as the value for its href attribute.

Screen Shot 2014-09-26 at 2.50.33 PM

The issue though is that if we click a link it still takes us to another page with just the image, we need to stop that. The event.preventDefault() method will do just that. If it is called, the default action of the event will not be triggered. So if it’s a link, it won’t take you to a page with that URL.

Screen Shot 2014-09-26 at 2.54.52 PM Screen Shot 2014-09-26 at 2.54.20 PM

Good progress. Though 1.1 is to show the overlay, we actually need to add the overlay to the document first. You do NOT want to add this to the HTML, but rather via the jQuery. This is because you don’t want to add any markup that’s unnecessary. If someone didn’t have JS turned on in their browser and you added the overlay in the html, they would then see that with everything else and it would be weird.

We’ll move this step to the top, remember, pseudocode order can be rearranged.

Screen Shot 2014-09-26 at 3.04.09 PM

Now, we want to use and do things (update the image/caption, hide and show it) to the overlay, so it’s best if we store it into a variable.

Screen Shot 2014-09-26 at 3.06.13 PM

But, this won’t do us much good, as it’s just storing that as a string, and we need it to be a jQuery representation of an object. jQuery lets you create a representation of a DOM element that isn’t part of the document yet, yet still use it in your code. This is called a disembodied element. Select the string and put $() around it. Also, it’s good to add a $ to the variable name, so you know it’s a jQuery representation of an object, and not a string or something. This is a common practice.

Screen Shot 2014-09-26 at 3.11.48 PM

This adds the div to the page, which we can then style.

Screen Shot 2014-09-26 at 3.16.44 PMScreen Shot 2014-09-26 at 3.16.53 PM

Since we want to hide it by default, rather than doing the .hide() method with jQuery, we’ll just do display: none; in the CSS. We’ll also add opacity, so it looks like all lightboxes for when we do eventually display it.

Screen Shot 2014-09-26 at 3.19.02 PM

Finally, because we made the div a jQuery object instead of just a string, we can use the show method on it directly, rather than having to do $(“#overlay”).

Screen Shot 2014-09-26 at 4.26.47 PM

Now we need the overlay to show the image that was clicked. We’l start by creating another jquery object that is an img tag. Then, even though the $overlay object hasn’t been appended to the body yet, we can still mess around with it and append the $image object to it. Now when it does get appended to the body, it will include and <img> tag.

Screen Shot 2014-09-26 at 4.29.38 PM

Now, we need the image in the overlay to update and show the correct image. We can use the attr() method again, this time to modify the src attribute for it.

Screen Shot 2014-09-29 at 12.40.30 PM

Now href as a variable name could get confusing later, so we’ll rename that variable to imageLocation. WE’ll also remove that console.log, since we don’t really need it anymore.

Screen Shot 2014-09-29 at 12.46.40 PM

Aside – I original made the overlay background: black; with opacity: .7;, but this actually made the image transparent as well. But, by doing rgba(0,0,0,.7);, it only made the overlay transparent and not the image.

We’ll now do some quick styling for the image, giving it a margin top of 10%, and giving its parent overlay a text-align:center so it is centered.

Screen Shot 2014-09-29 at 12.51.56 PMScreen Shot 2014-09-29 at 12.52.01 PM

Now, we want the overlay to go away when clicked again. We’ll start with the jQuery $overlay object and the click method, with an anonymous function. Within that, we can use $(this) or even the $overlay object with the hide() method.

Screen Shot 2014-09-29 at 12.59.06 PM

Time to add the caption. We’ll start by adding another disembodied element at the top, then appending that to our overlay, like we did for the $image earlier.

Screen Shot 2014-09-29 at 1.03.13 PM

So if you recall, the click event handler is tied to the link, but the links child img element has the alt attribute we need for the caption.

Screen Shot 2014-09-29 at 1.05.02 PM

We’ll look under the traversing the DOM section of the documentation for this, and see that the children() method is what we need here. We’ll start by using $(this), which selects the link we’ve clicked on, followed by children(“img”), which selects that link’s child img elements, follow by attr(“alt”), which gets that img’s alt attribute’s value. Finally, we’ll set all that equal to the variable captionText so we can use it later.

Screen Shot 2014-09-29 at 1.13.17 PM

Now we need to manipulate the $caption object to add the content of the captionText variable in there, so we’ll look under Manipulation this time, and find the text() method. NOTE: a lot of jQuery methods are setters ad getters. Usually, if you don’t pass in a parameter it will get you info from the selected element, and if you do, it will set info for that element.

So, we simply do  $caption.text(captionText);

Screen Shot 2014-09-29 at 1.21.17 PM

Slight issue, p text was black so you couldn’t see it unless you highlighted it, so we restyled it white.

Screen Shot 2014-09-29 at 1.22.34 PM

And on to the next one. Feels good to be back on track.