Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript

How to create navigation arrows with jQuery ( jQuery Basic course - Simple lightbox)

Hey, how can i create arrows to go through all the images for the already written code here : https://teamtreehouse.com/library/jquery-basics/creating-a-simple-lightbox/preparation

3 Answers

David Clausen
David Clausen
11,403 Points

Okay Got it all set-up for you:

//Problem: User when clicking on image goes to a dead end, poor UX
//Solution: Create an overlay with the large image - Lightbox

var $overlay = $('<div id="overlay"><div></div></div>');
var $image = $("<img>");
var $caption = $("<p></p>");

//Keep track of image index for prev/next, we will use a list index
//position to determine where we are and what it means to move forward
//and backwards by 1.
var $index = 0;

//this is grabbing the list items from the imageGallery element and
//we are assigning the length total
//this makes it flexible to expand the gallery or take away
var $galleryLength = $("#imageGallery li").length;

//2.1 An image
$overlay.children("div").append($image);


//2.2 add caption
$overlay.children("div").append($caption);

// Add some nav buttons and assign unique ids to them!
$overlay.children("div").append("<button id='btnPrev'> < </button>");
$overlay.children("div").append("<button id='btnNext'> > </button>");

//2. Add overlay
$("body").append($overlay);


// Update image overlay
// I moved the updating of the overlay to its own function
// since we use it three times in three differnet area, this makes code
// writting cleaner
var updateImage = function(imageLocation, imageCaption){

  //1.2 update the overlay with the image linked in the link
  $image.attr("src", imageLocation);

  //1.3 Get child <img> alt atrbute and set caption
  $caption.text(imageCaption);


}

//1. Click <a> event to an image
$("#imageGallery a").click(function(event){
  event.preventDefault();
  var imageLocation = $(this).attr("href");
  var imageCaption =  $(this).children("img").attr("alt");

  //update index to current selected image
  $index = $(this).parent().index(); 

  //this is calling that new Update overlay function above
  updateImage(imageLocation, imageCaption);

  //1.1 Show the overlay
  $overlay.slideDown(imageLocation);


});


//Button prev next function
var prevNext = function(prev ) {
  //set prev to true to move backwards in the index

  //if flag set move backwards, if not move forwards
  if(!prev) { $index++; }
  else { $index--; }

  //if out of index reset
  if ($index < 0) { $index = $galleryLength-1;}
  if ($index > 10) { $index = 0; }

  //Grab the element by index and then get the link
  var newImgSelected = $("#imageGallery li").get($index).getElementsByTagName("a");

  //grab link information
  var imageLocation = $(newImgSelected).attr("href");
  var imageCaption =  $(newImgSelected).children("img").attr("alt");

  //Update Overlay
  updateImage(imageLocation, imageCaption);
}

//Button events

$("#btnPrev").click(function(event){
  prevNext(true);
});

$("#btnNext").click(function(event){
  prevNext();
});



//3. When overlay is click
$overlay.click(function(event){
  //3.1 Hide the overlay  

    if(event.target.id == "overlay")
    $(this).slideUp("fast");

});

Like I said earlier change this part in your css:

#overlay div {
  display:block;
  background: white;
  width: 450px;
  /** Change from 350 to 370px to accommodate buttons **/
  height: 370px;
  margin: 10% auto;
  text-align: center;

To Test just copy and paste in your code, completely overwrite yours.

I strongly suggest you walk through my comments to understand it, ask any questions you need to.

i created buttons on my own and they are almost ready what i need to do more is remove class="selected" from the old image and add class="selected" to the new one so everything will work at 100% here are my codes:

HTML:

<div id="imageGallery">
        <div id="products-lineOne">
            <a href="img/rowOne/A-R1-Sfera.jpg">
                <img class="margin-right" src="img/rowOne/pressenting/pressenting-img1.jpg" alt="Product 1">
            </a>
            <a href="img/rowOne/A-R2-PG4.jpg">
                <img class="margin-right" src="img/rowOne/pressenting/pressenting-img2.jpg" alt="Product 2">
            </a>
            <a href="img/rowOne/A-R3-PG2.jpg">
                <img src="img/rowOne/pressenting/pressenting-img3.jpg" alt="Product 3">
            </a>
        </div>   

        <div id="products-lineTwo">
            <a href="img/rowTwo/B-R1-Sfera.jpg">
                <img class="margin-right" src="img/rowTwo/pressenting/pressenting-img1.jpg" alt="Product 4">
            </a>
            <a href="img/rowTwo/B-R2-PG4.jpg">
                <img class="margin-right" src="img/rowTwo/pressenting/pressenting-img2.jpg" alt="Product 5">
            </a>
            <a href="img/rowTwo/B-R3-PG1.jpg">
                <img src="img/rowTwo/pressenting/pressenting-img3.jpg" alt="Product 6">
            </a>
        </div>
</div>

Javascript (jQuery):

//Problem: User when clicking on image goes to a dead end
//Solution: Create an overlay with the large image- Lightbox

var $overlay = $('<div id="overlay"></div>');
var $image = $("<img>");
var $caption = $("<p></p>");
var $exit = $("<button><i class='fa fa-close fa-2x close'></i></button>");
var $buttonLeft = $("<button><i class='fa fa-arrow-left fa-2x arrow'></i></button>");
var $buttonRight = $("<button><i class='fa fa-arrow-right fa-2x arrow'></i></button>");


//Close button
$overlay.append($exit);

//An image to overlay
$overlay.append($image);

//A caption to overlay
$overlay.append($caption);

$overlay.append($buttonLeft);
$overlay.append($buttonRight);

//Add overlay
$("body").append($overlay);

//Capture the click even on a link to an image
$("#imageGallery a").click(function(event) {
    event.preventDefault();
    imageLocation = $(this).attr("href");
    currentImg = $(this);
    currentImg.addClass("selected");
    //Update overlay with the image linked in the link 
    $image.attr("src", imageLocation);

    //Show the overlay
    $overlay.slideDown("show");

    //Get child's alt attribute and set caption
    var $captionText = $(this).children("img").attr("alt");
    $caption.text($captionText);

    //Creating buttons
    $buttonLeft.click(function() {
        newImg = $("#imageGallery .selected").prev("a");
        newImgLocation = newImg.attr("href");
        $image.attr("src", newImgLocation);
    });

    $buttonRight.click(function() {
        newImg = $("#imageGallery .selected").next("a");
        newImgLocation = newImg.attr("href");
        $image.attr("src", newImgLocation);
    });

});

//When overlay is clicked
$exit.click(function() {
    //Hide the overlay
    $overlay.slideUp("slow");
});

And finally my css style code:

/** Coding **/

#overlay {
    background: rgba(0,0,0,0.7);
    width: 100%;
    height: 100%;
    position: absolute;
    top: 0;
    left: 0;
    z-index: 1;
    display: none;
    text-align: center;
}

#overlay img {
    margin-top: 10%;
}

#overlay p {
    position: relative;
    left: 30;
    color: aliceblue;
    font-family: 'Roboto Slab', serif;
    font-weight: 400;
    font-size: 1.5em;
    margin: 15px;
}

#overlay .close {
    position: relative;
    bottom: 430;
    left: 370;
    color: aliceblue;
    padding: 5px 10px;
    border: dashed 3px white;
    border-radius: 80%;
}

#overlay .arrow {
    position: relative;
    left: 30;
    color: aliceblue;
    padding: 5px 66px;
    border: solid 4px aliceblue;
    margin-left: 12px;
}
David Clausen
David Clausen
11,403 Points

Yah your close. Why did you nest your click functions? Shouldn't, less readable.

Also there is a jquery add class and remove class function.

Also what happens when you run out of siblings? Like does it loop around when you past the last picture?

Also will next("a") grab any next tags or the ones only in their parents? Which wouldn't be the next images? Not at a computer to test but some question to consider.

Store the new element you select, and then references the .selected again .removeclas("selected") or something and then call the element you saved and put .add class("selected") or something, got to look up the method for it.

Let me know how it goes.

What was the purpose of the

inside the
```<div id="overlay">```?
David Clausen
David Clausen
11,403 Points

The div inside div overlay is the div where image frame, image and button are inserted.

The document flow for the light-box goes:

overlay (which covers the webpage on tope) the div to contain the image elements including the button. then img, button and caption text are added inside that div.

The buttons are pushed outside the div cause the div is defined too small to not include the buttons in the white frame, but they are still being centered in the overlay cause they are contained in the div.

Hope that makes sense!

David Clausen
David Clausen
11,403 Points

You would need to add buttons to it. An easy way is insert a < and a > to the left and right side respectively. Then when your mouse clicks on it fire an event to go to next image in a list.

That is what im trying to do but i can't make for some reason.... Here is my code:

Javascript(jQuery):

 //Problem: User when clicking on image goes to a dead end
//Solution: Create an overlay with the large image- Lightbox

var $overlay = $('<div id="overlay"></div>');
var $image = $("<img>");
var $caption = $("<p></p>");
var $exit = $("<button><i class='fa fa-close fa-2x close'></i></button>");
var $buttonLeft = $("<button><i class='fa fa-arrow-left fa-2x arrow'></i></button>");
var $buttonRight = $("<button><i class='fa fa-arrow-right fa-2x arrow'></i></button>");


//Close button
$overlay.append($exit);

//An image to overlay
$overlay.append($image);

//A caption to overlay
$overlay.append($caption);

$overlay.append($buttonLeft);
$overlay.append($buttonRight);

//Add overlay
$("body").append($overlay);

//Capture the click even on a link to an image
$("#imageGallery a").click(function(event) {
    event.preventDefault();
    var imageLocation = $(this).attr("href");

    //Update overlay with the image linked in the link 
    $image.attr("src", imageLocation);

    //Show the overlay
    $overlay.show();

    //Get child's alt attribute and set caption
    var $captionText = $(this).children("img").attr("alt");
    $caption.text($captionText); 
});

//When overlay is clicked
$exit.click(function() {
    //Hide the overlay
    $overlay.hide();
});

HTML Code:

<div id="imageGallery">
        <div id="products-lineOne">
            <a href="img/rowOne/A-R1-Sfera.jpg">
                <img class="margin-right" src="img/rowOne/pressenting/pressenting-img1.jpg">
            </a>
            <a href="img/rowOne/A-R2-PG4.jpg">
                <img class="margin-right" src="img/rowOne/pressenting/pressenting-img2.jpg">
            </a>
            <a href="img/rowOne/A-R3-PG2.jpg">
                <img src="img/rowOne/pressenting/pressenting-img3.jpg">
            </a>
        </div>   

        <div id="products-lineTwo">
            <a href="img/rowTwo/B-R1-Sfera.jpg">
                <img class="margin-right" src="img/rowTwo/pressenting/pressenting-img1.jpg">
            </a>
            <a href="img/rowTwo/B-R2-PG4.jpg">
                <img class="margin-right" src="img/rowTwo/pressenting/pressenting-img2.jpg">
            </a>
            <a href="img/rowTwo/B-R3-PG1.jpg">
                <img src="img/rowTwo/pressenting/pressenting-img3.jpg">
            </a>
        </div>
</div>

Would love your help on these buttons :)

David Clausen
David Clausen
11,403 Points

Here is a start to getting some buttons:

var $overlay = $('<div id="overlay"><div></div></div>');
var $image = $("<img>");
var $caption = $("<p></p>");

//2.1 An image
$overlay.children("div").append($image);

//2.2 add caption
$overlay.children("div").append($caption);

//Add some buttons!!
$overlay.children("div").append("<button id='btnPrev'> < </button>");
$overlay.children("div").append("<button id='btnNext'> > </button>");

also i changed

This part is the css:

#overlay div {
  display:block;
  background: white;
  width: 450px;
  height: 370px;
  margin: 10% auto;
  text-align: center;

height:370px was 350px, i increased it to 370.

So you need to build a function to that act on the buttons when they are pressed.

There we go !! Thank you a lot for the support

//Creating buttons
    $buttonLeft.click(function() {
        newImg = $("#imageGallery .selected").prev("a");
        newImgLocation = newImg.attr("href");
        newImg.next().removeClass("selected");  //remove class
        newImg.addClass("selected");            //add clas
        $image.attr("src", newImgLocation);
    });

    $buttonRight.click(function() {
        newImg = $("#imageGallery .selected").next("a");
        newImgLocation = newImg.attr("href");
        newImg.prev().removeClass("selected");  //remove class
        newImg.addClass("selected");            //add class
        $image.attr("src", newImgLocation);
    });