jQuery custom Image gallery logic - javascript

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/

Related

Fade transition for jquery image swap

I'm somewhat new to jquery and I have this working function that swaps images on the hover of a list element. I am trying to add a fadeOut and fadeIn but its not working. The image fades out, but it doesn't get the correct path for the new image.
This is the working script:
$(document).ready(function() {
var path = 'images/';
$('.menu-child').hover(function() {
var newimage = $(this).attr('data-path') + '.jpg';
$('.swap > img').attr('src', path + newimage)
});
});
This is what I tried for fade effect (and a couple of variations, none of which I could get to work):
$(document).ready(function() {
var path = 'images/';
$('.menu-child').hover(function() {
var newimage = $('.menu-child').attr('data-path') + '.jpg';
$('.swap > img').fadeOut(function() {
$('.swap > img').attr('src', path + newimage).fadenIn();
});
});
});
HTML:
<section class="submenuWrapper">
<ul class="twinsub">
<li class="twinmultisub twinleft">
<ul>
<li class="menu-child" data-path="menu-interior"><span>Interior Painting</span></li>
<li class="menu-child" data-path="menu-exterior"><span>Exterior Painting</span></li>
</ul>
</li>
<li class="twinmultisub twinimg">
<section class="swap">
<img src="images/menu-exterior.jpg" />
</section>
</li>
</ul>
</section>
There we a couple of things.
Try this:
$(document).ready(function() {
var path = 'images/';
$('.menu-child').hover(function() {
var newimage = $(this).attr('data-path') + '.jpg';
$('.swap > img').fadeOut(function() {
$(this).attr('src', path + newimage).fadeIn();
});
});
});
Working Example: https://jsfiddle.net/sabrick/fudLgqxs/3/
You'll probably be able to figure out why it works now on your own, but let me know if you'd like any additional details.
Here is a sample with appropriate comments
$(document).ready(function() {
var path = 'images/';
$('.menu-child').hover(function() {
var newimage = $(this).attr('data-path') + '.jpg';
if(newimage != (path + $('.swap > img').attr('src'))){
/*if the current image being displayed is not the same
as the data-path of the hovered element.
This prevents it from running even when the image should
not be changing
*/
$('.swap > img').fadeOut(0);
//first fade out the current image
$('.swap > img').attr('src', path + newimage);
//then change the path when it is not visible
$('.swap > img').fadeIn(500);
//then fade in the new image with the new path
}
});
});

Find a src image value from an <a href> tag

I've been building an image gallery with pictures in the hundreds and I don't want them all to load on page load for obvious bandwidth issues. For starters, I put;
<body onload="removeAttr("src")">
to prevent the pictures from loading which works... too well I'm afraid as it doesn't load my website header banner pic. Anyhow, my gallery is set up with a menu with each button representing a different image. The menu is displayed in this format;
<ul id="menu">
<li>Title</li>
</ul>
with many buttons. When that button is clicked it loads the graphic linked with it into a div called "gallery" All the images are loaded into the "gallery" with overflow: hidden which is why they want to load initially, that code appears as;
<div id="gallery">
<div>
<a name="pic1"></a><img alt="" src="../images/characters/character1.jpg" />
</div>
</div>
Again with many images in it. My script listens for a mouse click and immediately grabs the
a href value associated with it, so "pic1", then it uses that to find the image name linked with it so "character1.jpg" and stores it in a variable. (Which I firmly believe is where my problem lies). It then, targeting the "gallery" div deletes any picture previously in there then inserts the new image (the one stored in a variable). All this is in an attempt to load only the graphic the user wants to see not all of them. That alert displays the button number so that part works, and I know it deletes the image loaded in the div as it seems to be loading the first image in the list which then vanishes upon testing, but then it never replaces it with a new one.
<script type="text/javascript">
window.onclick = function(e) {
var node = e.target;
while (node != undefined && node.localName != 'a') {
node = node.parentNode;
}
if (node != undefined) {
if (this.id == 'alternate-image') {
var Imgsrc = $(this).find('img').attr('src');
alert(src);
}
var dv = document.getElementById('gallery');
// remove all child nodes
while (dv.hasChildNodes()) {
dv.removeChild(dv.lastChild);
}
alert("The button value is: " + node);
var img = document.createElement("IMG");
img.src = Imgsrc;
dv.appendChild(img);
return false; // stop handling the click
} else {
alert('This is not a link: ' + e.target.innerHTML)
return true; // handle other clicks
}
}
</script>
Not sure if I fully understand your issue, but I do see an issue with your code.
You are defining var Imgsrc within an if block. If the expression is not true, then Imgsrc will not be defined. Yet later in your code you use it, regardless of conditions, without checking if it's defined in the first place.
See my code comments below.
<script type="text/javascript">
window.onclick = function(e) {
var node = e.target;
while (node != undefined && node.localName != 'a') {
node = node.parentNode;
}
if (node != undefined) {
if (this.id == 'alternate-image') {
var Imgsrc = $(this).find('img').attr('src'); //<!---- here you define the Imgsrc var
//but what if the this.id != 'alternate-image'??
alert(src);
}
var dv = document.getElementById('gallery');
// remove all child nodes
while (dv.hasChildNodes()) {
dv.removeChild(dv.lastChild);
}
alert("The button value is: " + node);
var img = document.createElement("IMG");
img.src = Imgsrc; //<!---- need to check if this is defined.
dv.appendChild(img);
return false; // stop handling the click
} else {
alert('This is not a link: ' + e.target.innerHTML)
return true; // handle other clicks
}
}
</script>
Any chance you can post your html or more detail so we can resolve this?
Can you post the full source on a GitHub gist or a pastebin?
Here's a simpler way to do it. You don't need to add and remove new image elements, just change the src attribute on an existing one.
<ul class='imageMenu'>
<li data-image="dog.jpg">dog</li>
<li data-image="cat.jpg">cat</li>
<li data-image="donkey.jpg">donkey</li>
</ul>
<img src="" id='selectedImage' />
<script>
const img = document.querySelector('#selectedImage');
document.querySelectorAll('.imageMenu li').forEach(item => {
item.addEventListener('click', evt => {
img.setAttribute('src', evt.target.getAttribute('data-image'));
});
});
</script>
I would propose a revised set of markup and code. Since you appear to have jQuery in your code, I will use that.
Menu of images:
<ul id="menu">
<li class="image-link" data-image="../images/characters/character1.jpg">Title 1</li>
<li class="image-link" data-image="../images/characters/character2.jpg">Title 2</li>
<li class="image-link" data-image="../images/characters/character3.jpg">Title 3</li>
</ul>
One place to show them:
<div id="gallery">
<img alt="" src="" />
</div>
Code to show them:
$('#menu').on('click','.image-link',function(){
$('#gallery').find('img').attr('src', $(this).data('image'));
});

Jquery selects second to last child

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');

Changing hover image after repeated hovers using Jquery

I am trying to change the src attribute in an img tag in html using jquery, I want scr attribute to change differently depending on the number of times the user has hovered over the img element.
My html is set up as follows:
<img id="element" src="img1.png">
My js/jQuery is set up as follows:
var count = 0;
if(count == 0){
$("#element").hover(function(){
count++;
$("#element").attr("src","img2.png");
}, function(){
$("#element").attr("src","img1.png");
});
} else if(count>=1){
$("#element").hover(function(){
count++;
$("#element").attr("src","img3.png");
}, function(){
$("#element").attr("src","img1.png");
});
}
The hover function on its own works fine, and hovering in and out will switch between two images. However, my goal is to make it switch to img2 in the first hover, and then img3 at the second hover, and thereafter. My hover function seems to work fine if I want it to hover between img1 and img2 or img 1 and img3, that is when I remove if statement and count variable.
If someone could help identify my problem please.
You need to do the counter check within the hover handler
var counter = 0;
$("#element").hover(function() {
$(this).attr("src", ++counter > 1 ? '//placehold.it/64X64/00ff00' : '//placehold.it/64X64/0000ff');
}, function() {
$(this).attr("src", "//placehold.it/64X64/ff0000");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<img id="element" src="//placehold.it/64X64/ff0000">
In your code the value of counter is checked only once on page load where the value of counter is always 0
From what you've posted, if(count == 0) occurs in your setup code. None of your hover event handlers touch the value of count, so once the handlers are set (either to 1 and 2 or 1 and 3), they will never be changed. And since count is always zero when the handlers are added, you always get the first pair.
Instead, you should switch between the two images inside of your handler function, not in the code that assigns the handler.
Try creating array of strings containing img src , utilizing Array.prototype.reverse() to toggle images
var imgs = ["img2.png", "img3.png"];
$("#element").hover(function() {
$(this).attr("src", imgs[0]);
imgs.reverse()
}, function() {
$(this).attr("src", "img1.png");
});
var imgs = ["http://lorempixel.com/100/100/sports", "http://lorempixel.com/100/100/cats"];
$("#element").hover(function() {
$(this).attr("src", imgs[0]);
imgs.reverse()
}, function() {
$(this).attr("src", "http://lorempixel.com/100/100/nature");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<img id="element" width="100px" src="http://lorempixel.com/100/100/nature" />
What about some simplicity?
var counter = 1;
$("#element").hover(function () {
counter = (counter===3) ? 1 : (counter+1);
$(this).attr("src", 'img'+counter+'.png');
}
Not sure if this will work just something I looked up but you can try it.
Just add more variables to it.
jQuery(document).ready(function($) {
//rollover swap images with rel
var img_src = "";
var new_src = "";
$(".rollover").hover(function(){
//mouseover
img_src = $(this).attr('src'); //grab original image
new_src = $(this).attr('rel'); //grab rollover image
$(this).attr('src', new_src); //swap images
$(this).attr('rel', img_src); //swap images
},
function(){
//mouse out
$(this).attr('src', img_src); //swap images
$(this).attr('rel', new_src); //swap images
});
How about this?
$(document).ready(function(){
var count = 1;
$("#element").hover(function() {
count++;
$(this).attr("src","img"+count+".png");
if(count == 3){
//Reset the count
count = 0;
}
}, function() {
$(this).attr("src", "img1.png");
});
});

Switching image with Next/Previous buttons

Is there any way to switch images using next/prev buttons with jQuery? Here's the code:
<div class="prevDiv">
<img src="images/prev.png" alt="previous" />
</div>
<div class="pic" id="picwebd">
<img src="images/portfolio/webdesign/webd1.jpg" class="portPic" />
</div>
<div class="nextDiv">
<img src="images/next.png" alt="previous" />
</div>
I tried modifying this code to my needs: http://jsfiddle.net/x5mCR/16/ but I haven't succeed. I think that incrementing and decrementing number in the image src would be enough, but I can't come up with decent code do this. Google doesn't help neither.
In case anyone reading this post want a different approach still using JQuery fadeIn, Im posting below the code for that.
Here you can find the fiddle for it.
Here's the Javascript Part
//At the start will show the first image
$('#fullimage img.fullimage:first-child').fadeIn();
//Keep track of the image currently being visualized
var curr = $('#fullimage img.fullimage:first-child');
$('#next').on('click', function() {
//Hide Current Image
curr.hide();
//Find Next Image
var next = curr.next();
//If theres no next image (is the last img), go back to first
if (next.length == 0) next = $('#fullimage img:first');
//Fade In
next.fadeIn();
//Save in curr the current Image
curr = next;
return false;
});
$('#prev').on('click', function() {
curr.hide();
var prev = curr.prev();
if (prev.length == 0) prev = $('#fullimage img:last');
prev.fadeIn();
curr = prev;
return false;
});
Here's the HTML part
<div id="fullimage">
<img class="fullimage" src="http://i.imgur.com/RHhXG.jpg" />
<img class="fullimage" src="http://i.imgur.com/p1L2e.jpg" />
<img class="fullimage" src="http://i.imgur.com/NsrI0.jpg" />
<img class="fullimage" src="http://i.imgur.com/Ww6EU.jpg" />
</div>
<label id="prev">previous</label>
<label id="next">next</label>
Here is dynamic and simple script reducing your html code
http://jsfiddle.net/x5mCR/32/
$("#thumbnail a").on('click', function (eve) {
eve.preventDefault();
var link = ($(this).attr("href"));
var content = '<img src="' + link + '"/>';
$("#fullimage").hide().html(content).fadeIn('slow');
});
Remove the anchors with class thumbnail and give the corresponding <img> tags the thumbnail class, then use jQuery click methods for the thumbnail class:
$(".thumbnail").click(function() {
$(".fullimage").src = $(this).attr("src");
});
Make sure you have a single .fullimage in the #fullimage div.
This isn't the same as a next / previous button - but it would fix the JSFiddle that you made.
http://jsfiddle.net/x5mCR/34/
var picNumber = 1;
$(".nextDiv").click(function() {
picNumber++;
if (picNumber > 3) picNumber = 1; // Change 3 to how many pictures there are.
$(".pic img").attr("src", "images/portfolio/webdesign/webd" + picNumber + ".jpg");
});
$(".prevDiv").click(function() {
picNumber--;
if (picNumber < 1) picNumber = 3; // Change 3 to how many pictures there are.
$(".pic img").attr("src", "images/portfolio/webdesign/webd" + picNumber + ".jpg");
});
If I understand correctly, you're trying to use the arrow keys to move back and forth between pictures...so if this is the case, I would recommend taking a look at this post: Binding arrow keys in JS/jQuery
Also, for your convenience, I just took the code from that post and combined it with the function in your fiddle to get this:
$(document).keydown(function (e) {
if (e.keyCode == 39) {
$(".fullimage").hide();
var next = $(this).next();
if (next.length > 0) {
next.fadeIn();
} else {
$('#fullimage img:first').fadeIn();
}
return false;
}
});
In testing it looks like it might need some modification, and also, you would obviously need to create a similar function for when the back button is pressed, but I think if I'm understanding your issue correctly this is a good starting place.

Categories