Get number of items by class within parent in JS - javascript

I have built an image gallery where there is one main image and up to 5 thumbnails under it. and can use left and right buttons to cycle through the thumbnails and replace the main image like so:
$(".gallery-btn-left").unbind("click").bind("click", function(){
var image_id = $(".gallery-main-image img").attr('data-id');
image_id--;
if(image_id == 0){image_id = $('.gallery-thumbnail img').length;}
var image_url = $(".gallery-thumbnail img[data-id=" + image_id + "]").attr('src');
$(".gallery-main-image img").attr('src', image_url);
$(".gallery-main-image img").attr('data-id', image_id);
});
$(".gallery-btn-right").unbind("click").bind("click", function(){
var image_id = $(".gallery-main-image img").attr('data-id');
image_id++;
if(image_id > $('.gallery-thumbnail img').length){image_id = 1;}
var image_url = $(".gallery-thumbnail img[data-id=" + image_id + "]").attr('src');
$(".gallery-main-image img").attr('src', image_url);
$(".gallery-main-image img").attr('data-id', image_id);
});
This all works fine, however, if I want to put two galleries on the same page I get an issue where by my JS is getting 10 instead of 5 or however may thumbnails there are (max 5 per gallery) for $('.gallery-thumbnail img').length which is expected.
What I want to know is if there is a way to get the length of the amount of thumbnails in the parent gallery rather than how many thumbnails there are on the page as a whole.

The most common approach for multiple instances is to look up to the container instance and then use find() within that instance.
Also when you look for the same selector multiple times it is best to store a reference to it rather than search the DOM every time you need to access it. It also makes the code a little easier to read
Something like:
$(".gallery-btn-left").unbind("click").bind("click", function() {
var $gallery = $(this).closest('.MAIN-GALLERY-CLASSNAME'),
$mainImg = $gallery.find(".gallery-main-image img"),
$thumbs = $gallery.find('.gallery-thumbnail img'),
image_id = $mainImg.attr('data-id');
image_id--;
if (image_id == 0) {
image_id = $thumbs.length;
}
var image_url = $thumbs.filter("[data-id=" + image_id + "]").attr('src');
$mainImg.attr({'src': image_url, 'data-id',image_id});
});

Related

JavaScript: For loop continues until end

I'm making a practice webpage with a list of guitars. What I want to do is when a thumbnail for the guitar Fender Telecaster is clicked, a for-loop runs through all the images with a class name of "gallery", takes that information and places it on various different parts of the DOM. Important things to know:
-- The thumbnails of these guitars all have class names of "gallery," and I have five guitars in this order: Fender Stratocaster, Fender Telecaster, Gibson Les Paul, Gibson SG, Gretsch Electromatic.
-- Each has a title which corresponds to the name of the guitar AND the file name of the various images related to the guitar (for example, the title "gibson-les-paul" and the image files are "gibson-les-paul.jpg" and "gibson-les-paul-big.jpg")
-- Each image thumbnail has four data attributes which JavaScript takes and places on the DOM.
THE PROBLEM: The for-loop works fine EXCEPT when I click any of the thumbnails the last image with a class of "gallery" (Gretsch Electromatic) and all of its information appears in the DOM. So if I click on any of the five, it takes information from the last element in the loop.
The first bit of code I have included just so the rest makes sense. It's the second bit of code I have trouble with:
function replaceNodeText(id, newText) {
var node = document.getElementById(id);
while (node.firstChild)
node.removeChild(node.firstChild);
node.appendChild(document.createTextNode(newText));
}
var gallery = "gallery";
var images = "images/";
var big = "-big.jpg";
// Above is all fine and good, it's below where the issue is:
function bigChange() {
var runThrough = document.getElementsByClassName(gallery);
for (var i = 0; i < runThrough.length; i++) {
var dataKey1 = runThrough[i].getAttribute("data-key1");
var dataKey2 = runThrough[i].getAttribute("data-key2");
var dataKey3 = runThrough[i].getAttribute("data-key3");
var dataKey4 = runThrough[i].getAttribute("data-key4");
var title = runThrough[i].getAttribute("title");
document.getElementById("popUpPic").src = images + title + big;
if (title != "fender-telecaster") {
document.getElementById("photo_large").src = images + title + ".jpg";
}
else {
document.getElementById("photo_large").src = images + title + ".png";
}
replaceNodeText("guitarTitle", dataKey1);
replaceNodeText("guitarBrand", dataKey2);
replaceNodeText("caption1", dataKey3);
replaceNodeText("guitarPrice", dataKey4);
}
}
Thanks in advance!
:-)
Try using break in your if/else statement so that it doesn't loop through all of the pictures

Javascript Slider title replace html for title just working on 1st item

Hi im building a slider using jquery tools.. here is my code http://jsfiddle.net/SmW3F/5/
Anyway, the problem is when you over the image is updated (the Main image) so each thumb update the main image on hover.
The problem is the title is just working for 1st item.. all other items are not updating the title..
here is this part of the code
var root = $(".scrollable").scrollable({circular: false}).autoscroll({ autoplay: true });
$(".items img").on("hover",function() {
// see if same thumb is being clicked
if ($(this).hasClass("active")) { return; }
// calclulate large image's URL based on the thumbnail URL (flickr specific)
var url = $(this).attr("src").replace("_t", "");
var tbtit = $("#tbtit").html();
var tbdesc = $("#tbdescp").html();
// get handle to element that wraps the image and make it semi-transparent
var wrap = $("#image_wrap").stop(true, true).fadeTo("medium", 0.5);
// the large image from www.flickr.com
var img = new Image();
// call this function after it's loaded
img.onload = function() {
// make wrapper fully visible
wrap.fadeTo("fast", 1);
// change the image
wrap.find("img").attr("src", url);
wrap.find(".img-info h4").replaceWith(tbtit);
wrap.find(".img-info p").replaceWith( tbdesc);
};
// begin loading the image from www.flickr.com
img.src = url;
// activate item
$(".items img").removeClass("active");
$(this).addClass("active");
// when page loads simulate a "click" on the first image
}).filter(":first").trigger("mouseover");
var count = 0;
var scroll_count = 0;
setInterval(function(){
count++; // add to the counter
if($(".items img").eq(count).length != 0){
console.log(count);
$(".items img").eq(count).trigger("mouseover");
if(count % 5 === 0)
{
I found a couple of issues with your script, but first you have invalid markup in your page since you have multiple <div> elements with the same ids of tbtit and tbdescp. Id attributes should be unique in a HTML page so should change those to classes instead.
Now in your script you need to change the part where you retrieve the values of the title and the description of the image that is hovered to reference the sibling elements:
//THIS
var tbtit = $("#tbtit").html();
var tbdesc = $("#tbdescp").html();
//SHOULD NOW BE THIS
var tbtit = $(this).siblings('.tbtit').text();
var tbdesc = $(this).siblings('.tbdescp').text();
Finally when you update the text for your main image you want to set the content for your <h4> and <p> tags and not replace them completely, so use .text()
//THIS
wrap.find(".img-info h4").replaceWith(tbtit);
wrap.find(".img-info p").replaceWith( tbdesc);
//SHOULD NOW BE THIS
wrap.find(".img-info h4").text(tbtit);
wrap.find(".img-info p").text( tbdesc);

Loading A text along with a picture using AJAX

I have made a photo gallery in my website using the following:
/*Begin Photo Gallery Code*/
var images = ['g1.jpg', 'g2.jpg', 'g3.jpg', 'g4.jpg'];
function loadImage(src) {
$('#pic').fadeOut('slow', function() {
$(this).html('<img src="' + src + '" />').fadeIn('slow');
});
}
function goNext() {
var next = $('#gallery>img.current').next();
if(next.length == 0)
next = $('#gallery>img:first');
$('#gallery>img').removeClass('current');
next.addClass('current');
loadImage(next.attr('src'));
}
$(function() {
for(var i = 0; i < images.length; i++) {
$('#gallery').append('<img src="images/gallery/' + images[i] + '" />');
}
$('#gallery>img').click(function() {
$('#gallery>img').removeClass('current');
loadImage($(this).attr('src'));
$(this).addClass('current');
});
loadImage('images/gallery/' + images[0]);
$('#gallery>img:first').addClass('current');
setInterval(goNext, 4000);
});
It loads one picture at a time from a set of four pictures. Also I have four html files, each of them being relevant to one of the pictures. I want to use JavaScript/JQuery/AJAX to load the relevant html file's content along with the shown picture. Does anyone have an idea how I can do this?
Should I put the ajax files (4 html files) into a JavaScript array or something?
var ajaxPages=['ajax1.html','ajax2.html','ajax3.html','ajax4.html'];
Thanks in advance.
Unless the HTML files supposed to change somehow during their displaying, should either output them via your server-side code in hidden divs with the request (would be the correct way of doing it) or use AJAX to save them in a variable or create hidden divs.
First you need two arrays like this:
var ajaxPages=['ajax1.html','ajax2.html','ajax3.html','ajax4.html'];//File Names
var divPages=['div1','div2','div3','div4'];//Div ids in order
For the AJAX part you should use something like:
var getHtml = function(filename,divid){
$.post('html/'+filename, function(data) {
//The first argument is your file location
//Second one is the callback, data is the string retrieved
$('#'+divid).html(data);
});
}
$.each(ajaxPages,function(index,value){
getHtml(value,divPages[index]);
});
That should do it... Do tell me if you require further explanation.
EDIT:
var ajaxPages=['ajax1.html','ajax2.html','ajax3.html','ajax4.html'];
var divId="yourdivid";
var textArray=new Array();
var currentImg=0;
var getHtml = function(filename){
$.post('html/'+filename, function(data) {
textArray.push(data);//Save data inside the array textArray
});
}
$.each(ajaxPages,function(index,value){
getHtml(value,divPages[index]);
});
Then your goNext() method:
function goNext() {
var next = $('#gallery>img.current').next();
if(next.length == 0){
next = $('#gallery>img:first');
currentImg=0;
}else{
currentImg++;
}
$('#gallery>img').removeClass('current');
next.addClass('current');
loadImage(next.attr('src'));
$('#'+divId).html(textArray[currentImg]);//Adds text to div based on current picture
}
That should be working fine!

jQuery Image Load Loop - Wrap HTML & Check Size?

I have a folder with images in it and I'm loading those images using jQuery. This code:
$(function () {
var i=1;
for (i=1;i<=50;i++){
var curImg = "blog/wp-content/uploads/" + i + ".jpg";
var img = new Image();
$(img).load(function () {
$(this).hide();
$('#loader').removeClass('loading')
.append(this);
$(this).fadeIn();
}).error(function () {})
.attr('src', ''+curImg+'');
}
});
works fine for smoothly loading 50 images from this folder. I am trying to do 2 things:
I want to add a link like this: <a href='blog/wp-content/uploads/" + i + ".jpg' class='picLink'> to each individual image. I have tried using .wrap in my .load function here, but that isn't working for me. This just creates a nest of links (e.g. <a><a></a></a>).
Currently this finds the first 50 photo's, starting at number 1, and loads them. But if more photo's are added they won't be found, and the oldest will always be first. I would like it to find all photo's in the folder and print the newest (highest number) first. It can be presumed that there won't be more than, say, 4000 photo's. So would it be possible to do this loop in reverse, start at 4000, check if that photo exists and work down and just load photo's that exist in the folder?
Thanks in advance for any help, I hope the question is clear enough!
For 1. you can do something like this fiddle
$(function () {
var i=1;
for (i=1;i<=50;i++){
var curImg = "blog/wp-content/uploads/" + i + ".jpg";
var img = new Image();
$(img).load(function () {
$(this).hide();
$('#loader').removeClass('loading')
.append($('').append(this));
$(this).fadeIn();
}).error(function () {})
.attr('src', ''+curImg+'');
}
});
Also they may not be in order as some images may take longer to load than others.
For 2. I think you should get the image count server-side and inject it into the for loop something like,
for (i=<?php echo $count; ?>; i > <?php echo ($count>50?$count-50:0); ?>; i--){
assuming you're using php, where $count represents the amount of images in the folder.

dynamic <img> refresh with javascript

I'm trying to get an user input image to refresh say every two seconds. The javascript gets user input for an URL and the javscript adds it to the page. Then the images loaded need to refresh every 2 seconds but i can't get it to refresh properly without refreshing the whole page or reloading from the cache:
function getImg(){
var url=document.getElementById('txt').value;
var div=document.createElement('div');
div.className="imageWrapper";
var img=document.createElement('img');
img.src=url;
div.appendChild(img);
document.getElementById('images').appendChild(div);
return false;
}
setInterval(function(){
$('img').each(function(){
var time = (new Date()).getTime();
$(this).attr("src", $(this).attr("src") + time );
});
}, 2000);
any ideas?
When you need to force reload the resource, you have to add a dymmy queryString at the end of your url:
<img id="img1" src="myimg.png?dummy=23423423423">
Javascript:
$('#img1').attr('src','myimg.png?dummy=23423423423');
and change the dummy value for each refresh
Your premise seems good, not sure why it isn't working. Why mixing and matching jQuery with non-jquery? This is a modification of your code, but it is a working example. You should be able to adapt it for your purpose.
http://jsfiddle.net/zr692/1/
You can create elements via jQuery easily. See the modified getImg function I created. Ia also switched from attr to prop which is the recommended means of accessing the src attribute in jQuery 1.7+.
function getImg() {
var url = 'http://placehold.it/300x300/123456';
var $div = $('<div />');
var $img = $('<img />', { src: url });
$div.append($img);
$('body').append($div);
}
getImg();
var interval = setInterval(function() {
$('img').each(function() {
var time = (new Date()).getTime();
var oldurl = $(this).prop('src');
var newurl = oldurl.substring(0, oldurl.lastIndexOf('/') + 1) + time.toString().substr(7, 6);
$('#output').html(newurl);
$(this).prop('src', newurl);
});
}, 2000);
Put the image in a container as:
<div id="container"><img src=""../> </div>
then simply update the content of the container as:
$('#container').html('<img src="newSource"../>');

Categories