Jquery selects second to last child - javascript

An interesting thing has happened as I build an light box using Jquery. I've set up left and right arrow buttons to move through the list so that at the last child the right arrow button begins again from the first child or at the first child, the left arrow button moves to the last child.
What's happening is that my left arrow button is supposed to move from the first child to the last child but instead is skipping over the last child and displaying the photo of the second to last child. I'm not having the same problem with the right arrow button moving from the last child to the first.
Also, when I click the left arrow and console.log the last child, I get the very image that I want to display logged correctly, but the image in the overlay is the second to last image.
<body>
<h1>Image Gallery</h1>
<ul id="imageGallery">
<li>
<a href="images/refferal_machine.png">
<img src="images/refferal_machine.png" width="100" alt="Refferal Machine By Matthew Spiel">
</a>
</li>
<li><img src="images/space-juice.png" width="100" alt="Space Juice by Mat Helme"></li>
<li><img src="images/education.png" width="100" alt="Education by Chris Michel"></li>
<li><img src="images/copy_mcrepeatsalot.png" width="100" alt="Wanted: Copy McRepeatsalot by Chris Michel"></li>
<li><img src="images/sebastian.png" width="100" alt="Sebastian by Mat Helme"></li>
<li><img src="images/skill-polish.png" width="100" alt="Skill Polish by Chris Michel"></li>
<li><img src="images/chuck.png" width="100" alt="Chuck by Mat Helme"></li>
<li><img src="images/library.png" width="100" alt="Library by Tyson Rosage"></li>
<li><img src="images/boat.png" width="100" alt="Boat by Griffin Moore"></li>
<li><img src="images/illustrator_foundations.png" width="100" alt="Illustrator Foundations by Matthew Spiel"></li>
<li><img src="images/treehouse_shop.jpg" width="100" alt="Treehouse Shop by Eric Smith"></li>
</ul>
<script src="http://code.jquery.com/jquery-1.11.0.min.js" type="text/javascript" charset="utf-8"></script>
<script src="js/app.js" type="text/javascript" charset="utf-8"></script>
</body>
The JavaScript:
var $overlay = $('<div id="overlay"></div>');
var $image = $('<img>');
var $caption = $('<p></p>');
var $arrowLeft = $('<button id="left" class="arrow">‹</button>');
var $arrowRight = $('<button id="right" class="arrow">›</button>');
var $exit = $('<button id="exit">X</button>');
//Add image to overlay
$overlay.append($image);
//Add buttons to overlay
$overlay.append($arrowRight);
$overlay.append($arrowLeft);
$overlay.append($exit);
//Add caption to overlay
$overlay.append($caption);
//Add overlay
$('body').append($overlay);
//Capture the click event 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 atribute and set caption
var captionText = $(this).children('img').attr('alt');
$caption.text(captionText);
});
//When left arrow is clicked
$arrowLeft.click(function() {
$('#imageGallery li a img').each(function() {
var galleryImage = $(this);
if (galleryImage.attr('src') === $image.attr('src')) {
var li = galleryImage.parent().parent();
if (li.is(':first-child')) {
var gallery = li.parent();
var lastLi = gallery.children(':last-child');
var anchor = lastLi.children('a');
var image = anchor.children('img');
$image.attr('src', image.attr('src'));
console.log(lastLi);
} else {
var prevLi = li.prev();
var anchor = prevLi.children('a');
var image = anchor.children('img');
$image.attr('src', image.attr('src'));
return false;
}
}
});
});
//When right arrow is clicked
$arrowRight.click(function() {
$('#imageGallery li a img').each(function() {
var galleryImage = $(this);
if (galleryImage.attr('src') === $image.attr('src')) {
var li = galleryImage.parent().parent();
if (li.is(':last-child')) {
var gallery = li.parent();
var firstLi = gallery.children(':first-child');
var anchor = firstLi.children('a');
var image = anchor.children('img');
$image.attr('src', image.attr('src'));
} else {
var nextLi = li.next();
var anchor = nextLi.children('a');
var image = anchor.children('img');
$image.attr('src', image.attr('src'));
return false;
}
}
});
});
//When x button is clicked
$exit.click(function() {
//Hide the overlay
$overlay.hide();
});

Update 1:
In the handler, you are running an each loop to test each image element, so make sure return false; is used when you find the matching image, otherwise your loop runs one more time after a match:
//When left arrow is clicked
$arrowLeft.click(function() {
$('#imageGallery li a img').each(function() {
var galleryImage = $(this);
if (galleryImage.attr('src') === $image.attr('src')) {
var li = galleryImage.parent().parent();
if (li.is(':first-child')) {
// if code block
...
} else {
// else code block
...
}
// move this to here
return false;
}
});
});
Make sure to update the arrow right handler as well.
You have an incorrect variable in your click handler:
//When left arrow is clicked
$arrowLeft.click(function() {
if (li.is(':first-child')) {
var gallery = li.parent();
var lastLi = gallery.children(':last-child');
var anchor = lastLi.children('a');
var image = anchor.children('img');
$image.attr('src', image.attr('href'));
console.log(lastLi);
} else {
...
});
Should be:
$image.attr('src', image.attr('src'));
You should look into joining that logic into one handler function to reduce the amount of code.
Also you can simplify this:
var li = galleryImage.parent().parent();
to this:
var li = galleryImage.closest('li');

Related

How do i let user keep clicking on an image and change the image

This is my javascript: It basically allows users to click on the second image (thermometer) and it will change to a slightly higher temperature AND at the same time, the beaker will be changed too accordingly. How do i let the user keep on clicking and the image to respond accordingly?
$(document).ready(function () {
$("#image").click(function () {
//when image is clicked, change image
var img2 = document.getElementById('image2');
img2.src = "images/beaker1.png";
var img = document.getElementById('image');
img.src = "images/t1.png";
return false;
});
});
Html file:
<div class="col-sm-6">
<img id="image2" src="images/beaker0.png" class="img-rounded">
<img src="images/saturated_percipitate_1.png" class="img-rounded">
</div>
<div class="col-sm-6">
<p><b>Increase Temperature</b></p>
<img id="image" src="images/t0.png" class="img-rounded"/>
<p><b>Decrease Temperature</b></p>
</div>
</div>
If I understand you correctly, maybe this what you are looking for.
The idea is to use counter for current image shown.
$(document).ready(function () {
var indexImage = 1;
$("#image").click(function () {
//check if thermometer is at max.
if(indexImage > 13){ //13 is example maximum value.
return false;
}
//when image is clicked, change image
var img2 = document.getElementById('image2');
img2.src = "images/beaker" + indexImage + ".png";
var img = document.getElementById('image');
img.src = "images/t" + indexImage + ".png";
indexImage++;
return false;
});
});
Add a class notSelected to your image
<img id="image2" src="images/beaker0.png" class="img-rounded notSelected">
then try toggling this class and add src attribute depending on a certain class. This should work:
$("#image").on('click',function(){
$("#image2").toggleClass("selected notSelected");
// change image
$("img.selected").attr('src','images/beaker1.png');
$("img.notSelected").attr('src','images/t1.png');
});
Hope this helps.

I having trouble getting my caption to show up in my lightbox

I have a lightbox and i have it able to scroll from one image to another, but since adding the forward and back buttons i lost my caption that used to be there. If anyone could help me figure it out i would appreciate it.
var $overlay = $('<div id="overlay"></div>');
var $image = $("<img>");
var $caption = $("<p></p>");
//An image to overlay
$overlay.append($image);
var $leftArrow = $("<div id='leftArrow'></div>");
var $rightArrow = $("<div id='rightArrow'></div>");
var $closeLightbox = $("<div id='closeLightbox'></div><div style='clear:both'></div>");
$image.before($closeLightbox);
$image.before($leftArrow);
$image.after($rightArrow);
//A caption to overlay
$overlay.append($caption);
//Add overlay
$("body").append($overlay);
//Capture the click event on a link to an image
$("#boxCabinet a,#channelLetters a, #customSignage a, #postandpanel a").click(function(event){
event.preventDefault();
getCurrentImage(this);
//Show the overlay.
$overlay.show();
});
$leftArrow.click(function(){
getPrevImage();
});
$rightArrow.click(function(){
getNextImage();
});
function getCurrentImage (currentImage) {
thisImage = currentImage;
var imageLocation = $(currentImage).attr("href");
//Update overlay with the image linked in the link
$image.attr("src", imageLocation);
//Get child's alt attribute and set caption
var captionText = $(this).children("img").attr("alt");
$caption.text(captionText);
}
function getPrevImage() {
imageParent = $(thisImage).parent().prev();
if(imageParent.length!=0){
thisImage = $(imageParent).children("a");
}
getCurrentImage(thisImage);
}
function getNextImage() {
imageParent = $(thisImage).parent().next();
if(imageParent.length!=0){
thisImage = $(imageParent).children("a");
}
getCurrentImage(thisImage);
}
//When overlay is clicked
$closeLightbox.click(function(){
//Hide the overlay
$overlay.hide();
});
And heres my html
<div id="slideshow">
<a name="featured" id="featured"></a>
<h1>Featured Work</h1>
<div id="ssouter">
<% csv.each do |row|%>
<% if row[2] == "Active" && row[4] == "Featured" %>
<img class="slideshow" src=<%= row[0]%> >
<% end %>
</div>
</div>
<div id="portfolio">
<a name="boxCabinet"></a>
<h1>Box Cabinet </h1>
<ul id="boxCabinet">
<% csv.each do |row|%>
<% if row[3] == "Box" && row[2] == "Active" %>
<li><img src=<%= row[0]%> width="120" height="120"alt="<%=row[1]%>"></li>
<% end %>
<% end %>
</ul>
I fixed it my problem was here.
//Get child's alt attribute and set caption
var captionText = $(this).children("img").attr("alt");
$caption.text(captionText);
}
I accidentally changed $(this).children when it should be $(currentImage).children
currentImage is when/where the caption is needing to be called so I see my error now.It came to me in my sleep, totally forgot til I started working on my code a few minutes ago.
All you'd have to do is to make title attribute of image links use image captions instead of link titles. It would require some modifications in your theme I guess, but the end result should be like that:
<img src="...">
Getting image captions for your attachments is quite well described: here

circular linked list not working as expected (jquery)

I created a circular linked list to transverse through an ul of images (i made an image gallery and am using the linked list to go through the images with the left and right arrow keys). Everything works fine until I get to the end of the list and try to go back to the first picture (or pressing left, when i get to the beginning and try to get to the last). This is my first time using jQuery and I'm not very good with circular linked lists (i only had to use one once--for school) and it seems like the problem is the if/else statement in my getNextPic function.
BTW I know this is really sloppy. Like I said, first time, so I'm sorry if it's a little difficult to follow. I'm posting a lot of my code because I always see people on here not posting enough to find the problem. Most of this i know works fine. The problem lies in getNextPic function as I said, 3rd snippet down. Thank you to anyone who attempts to help :)
here is a fiddle
html
<div id="gallery">
<div id="main">
<img id="main_img" src="d:/allyphotos/amanda_1.jpg" alt=""/></div>
<div id="thumbnail">
<ul>
<li><img class="thumb" id="long" src="d:/allyphotos/thumb/olivia_2.jpg"/></li>
<li><img class="thumb" id="long" src="d:/allyphotos/thumb/autumn_1.jpg"/></li>
<li><img class="thumb" id="long" src="d:/allyphotos/thumb/olivia_2.jpg"/></li>
<li><img class="thumb" id="long" src="d:/allyphotos/thumb/autumn_1.jpg"/></li>
<li><img class="thumb" id="long" src="d:/allyphotos/thumb/olivia_2.jpg"/></li>
<li><img class="thumb" id="long" src="d:/allyphotos/thumb/autumn_1.jpg"/></li>
<li><img class="thumb" id="long" src="d:/allyphotos/thumb/olivia_2.jpg"/></li>
<li><img class="thumb" id="long" src="d:/allyphotos/thumb/autumn_1.jpg"/></li>
</ul>
</div>
</div>
jQuery
document ready function
$(document).ready(function(){
//these ($first and $last) dont change
var $first = $('li:first img', '#gallery ul');
var $last = $('li:last img', '#gallery ul');
//set to current selected image to be displayed
var current = $first;
var previousImage = current;
runGallery(current, $first, $last, previousImage);
});
my runGallery function
function runGallery($current, $first, $last, previousImage){
//first and last thumbnails, selected and current
$("body").keydown(function(e){
// left arrow pressed
if ((e.keyCode || e.which) == 37)
{ $current = getNextPic($current, $first, $last, false);//false gets previous img, true gets following img
fade($current, previousImage);//fade selected, unfade previously selected
previousImage=$current;
var newlink = $($current).attr('src').replace('thumb/', '');
$('#main_img').attr('src', newlink);//set $current to main_img
}
// right arrow pressed
if ((e.keyCode || e.which) == 39)
{
$current = getNextPic($current, $first, $last, true);
fade($current, previousImage);
previousImage=$current;
var newlink = $($current).attr('src').replace('thumb/', '');
$('#main_img').attr('src', newlink);
}
});
$("#gallery li img").click(function()
{
//fade selected and unfade previous selected
fade(this, previousImage);
$current = this;
previousImage = this;
//get src for clicked thumb and change to full version
var newlink = $(this).attr('src').replace('thumb/', '');
$('#main_img').attr('src', newlink);
});
var imgSwap =[];
$("gallery li img").each(function()
{
imgUrl = this.src.replace('thumb/','');
imgSwap.push(imgUrl);
});
$(imgSwap).preload();
}
my getNextPic function -- this is where I believe the problem lies. I have commented the lines that aren't working properly
function getNextPic(current, first, last, boolval)
{
var next = $(current).closest('li');
if(boolval===true)
{
if(current === last)
{
next = first;//this seems to never happen???
}
else
{
next = $(next).next('li');
next = $(next).find('img');
}
}
else
{
if(current === first)
{
next = last;//this also never happens
}
else
{
next = $(next).prev();
next = $(next).find('img');
}
}
return next;
}
my fade function, 99.999% sure this has absolutely nothing to do with the problem but posting it anyway
function fade(current, previous)
{
$(previous).fadeTo('fast',1);
$(current).fadeTo('fast', 0.5);
}
The preload function, which i did not write (i got it from a tutorial) but i know isnt contributing to the problem. Posting so anyone who looks can rule it out too.
$.fn.preload = function(){
this.each(function(){
$('<img/>')[0].src=this;
});
}
Comparison of jquery objects cannot be done directly.
Your code contains, for example
current === last
Instead, as suggested in this answer, use the inner object:
You need to compare the raw DOM elements, e.g.:
if ($(this).parent().get(0) === $('body').get(0))
or
if ($(this).parent()[0] === $('body')[0])
Check out this fixed fiddle for your expected results.

How to find image src which is next in list of images

I have my code like this for the image gallery
<div id="panel">
<div id="img-grp-wrap">
<div class="img-wrap">
<img id="largeImage" src="images/1_large.jpg" />
<div id="description">1st image description</div>
</div>
<img src="arrowright.jpg" class="next" alt="Next"/>
<img src="arrowleft.jpg" class="prev" alt="Previous"/>
</div>
</div>
<div id="thumbs" class="content mThumbnailScroller">
<ul>
<li><img src="images/ind_thumb.jpg" alt="1st image description" /></li>
<li><img src="images/pak_thumb.jpg" alt="2nd image description" /></li>
<li><img src="images/sl_thumb.jpg" alt="3rd image description" /></li>
<li><img src="images/nz_thumb.jpg" alt="4th image description" /></li>
<li><img src="images/ban_thumb.jpg" alt="5th image description" /></li>
<li><img src="images/uae_thumb.jpg" alt="6th image description" /></li>
<li><img src="images/sa_thumb.jpg" alt="7th image description" /></li>
</ul>
</div>
And the JavaScript code as
$('.next').click(function() {
var curr = $('#largeImage').attr('src');
curr = curr.replace('large','thumb');
var next = $('#thumbs li').next('img[src=' + curr + ']').attr('id');
alert(next);
});
if curr value is "images/ban_thumb.jpg". so i want to alert next value to be
"images/uae_thumb.jpg" i.e the next image src and same for the previous img src of curr.
These will find the next and previous image sources. Note you need quotes for the src attribute since it has a slash:
$('.next').click(function() {
var curr = $('#largeImage').attr('src');
curr = curr.replace('large','thumb');
var next = $('img[src="' + curr +'"]')
.parent('li')
.next()
.find('img').attr('src');
alert(next);
});
$('.prev').click(function() {
var curr = $('#largeImage').attr('src');
curr = curr.replace('large','thumb');
var prev = $('img[src="' + curr + '"]')
.parent('li')
.prev()
.find('img').attr('src');
alert(prev);
});
You need to keep track of the images (You could use an array for this) and then populate the array by finding all of the images within the DOM.
When the button is clicked you can use the array and retrieve the image source, for instance.
var arr = [];
var count = 0;
$("#thumbs li img").each(function() {
var item = $(this).attr("src");
arr.push(item);
});
$(".next").click(function() {
$("input").val(arr[count]);
count++;
});
http://jsfiddle.net/oo7sdjdm/1/
Here is a simple solution with some good practices like using ID, grouping variables, caching the jQuery Object .. We'll use a counter to get the next and previous and a small function to get the image by index et voilà:
var i = 0, // Counter
$images = $('#thumbs').find('img'), // Cache the jQuery object
total = $images.length,
getCurrentItem = function () {
var currentItem = Math.abs(i % total), // Get item index
$currentItem = $images.eq(currentItem), // Current item object
currentItemSrc = $currentItem.attr('src').replace('thumb', 'large');
alert(currentItemSrc);
};
$('.next').on('click', function () {
i++;
getCurrentItem();
});
$('.prev').on('click', function () {
i--;
if (i < 0) {
i = total - 1; // If negative go back to the last image
}
getCurrentItem();
});

jQuery custom Image gallery logic

I've tried to customise colorbox on this page so that the main image display launches colorbox, but clicking any of the thumbs just swaps the image into the main image display. This is working fine but one niggling issue is best to handle the indexing/numbering - as I don't want the same image to appear twice in the lightbox image group, and I also want the correct index of the image to show and for the sequence to correspond with the thumbnail sequence. If anyone could see how to improve what I have at the moment that would be great.
The JS I currently have is:
$j(document).ready(function(e) {
function initColorbox() {
$j(".product-gallery").colorbox({
rel : "product-gallery",
current : function() {
var currImg = $j(this).attr("href");
// Grab basename, as initial main image url can differ from corresponding thumb url
var baseName = currImg.replace(/^.*\/|\.[^.]*$/g, '');
var pos;
var total = $j(".more-product-views li a").length;
// Check index by searching for filename in list items
$j(".more-product-views li a").each(function() {
if ($j(this).attr("href").indexOf(baseName) != -1) {
pos = $j(this).parent().index();
}
});
return "" + (pos + 1) + " of " + total;
},
onOpen : updateGallery,
onComplete : function() {
$j("#cboxTitle").hide();
}
});
}
function updateGallery() {
// Remove main product image's corresponding thumb from colorbox group to prevent duplication
var mainProdImg = $j(".main-prod-img").attr("href");
// Grab basename, as initial main image url can differ from corresponding thumb url
var mainProdBaseName = mainProdImg.replace(/^.*\/|\.[^.]*$/g, '');
$j(".more-product-views li a").each(function() {
if ($j(this).attr("href").indexOf(mainProdBaseName) != -1) {
$j(this).removeClass("product-gallery");
} else {
$j(this).addClass("product-gallery");
}
});
// Re-init gallery
initColorbox();
}
initColorbox();
updateGallery();
$j(".prod-more-view").click(function() {
var imgFull = $j(this).attr("href");
$j(".product-image a").attr("href", imgFull);
$j(".product-image img").attr("src", imgFull);
return false;
});
});
you can init the colorbox and use the .click of the ".product-gallery" like they do on the colorboxFAQ
var $gallery = $("a[rel=gallery]").colorbox();
$("a#openGallery").click(function(e){
e.preventDefault();
$gallery.eq(0).click();
});
to change the ".main-prod-img" when you click on the ".product-gallery" and only trigger the colorbox when click on ".main-prod-img" you need to check for event.originalEvent if it is not undefined then you return false
var $j = jQuery.noConflict();
$j(document).ready(function(e) {
//Create the colorbox
var $gallery = $j(".product-gallery").colorbox({
rel:"product-gallery",
onComplete : function() {
$j("#cboxTitle").hide();
}
});
//open colorbox on the right image
$j(".main-prod-img").click(function(e){
e.preventDefault();
var currImg = $j(this).attr("href");
var baseName = currImg.replace(/^.*\/|\.[^.]*$/g, '');
var pos;
var total = $j(".more-product-views li a").length;
$j(".more-product-views li a").each(function() {
if ($j(this).attr("href").indexOf(baseName) != -1) {
pos = $j(this).parent().index();
}
});
$gallery.eq(pos).click();
});
//change .main-prod-img src if e.originalEvent is not undefined or open the color box
$gallery.click(function(e) {
var imgFull = $j(this).attr("href");
$j(".product-image a").attr("href", imgFull);
$j(".product-image img").attr("src", imgFull);
if(e.originalEvent){
return false;
}
});
});
on $j(".main-prod-img").click you need to search for the index of the image in list items and trigger the right ".product-gallery" click like this $gallery.eq(pos).click();
the HTML
<div class="wrapper">
<div class="product-img-box">
<p class="product-image product-image-zoom">
<img src="ohoopee3.jpg">
</p>
<div class="more-views">
<ul class="more-product-views">
<li>
<img src="ohoopee3.jpg" width="56" height="56">
</li>
<li>
<img src="ohoopee2.jpg" width="56" height="56">
</li>
<li>
<img src="ohoopee1.jpg" width="56" height="56">
</li>
<li>
<img src="marylou.jpg" width="56" height="56">
</li>
</ul>
</div>
</div>
</div>
http://jsfiddle.net/bq2fW/

Categories