adding counter to a jquery slideshow - javascript

I'm using a slideshow I've built with Javascript for my website.
I would like to add a counter.
1 of 3...
slide 1 / total slide...
I can't manage to find the solution...
here is my code :
$(document).ready(function() {
// set display:none for all members of ".pic" class except the first
$('.image_news:gt(0)').hide();
// stores all matches for class="pic"
var $slides = $('.image_news');
$slides.click(function(){
// stores the currently-visible slide
var $current = $(this);
if( $current.is($slides.last()) ) {
$current.hide();
$slides.first().show();
}
// else, hide current slide and show the next one
else {
$current.hide().next().show();
}
});
});
and a fsfiddle link with example : http://jsfiddle.net/XRpeA/3/
thanks a lot for your help !

Write this:
var count = $('.image_news').length; //length gives total length of elements
$("#total").text(count);
if ($current.is($slides.last())) {
$("#current").text("1");//first slide
$current.hide();
$slides.first().show();
}
// else, hide current slide and show the next one
else {
$("#current").text($current.next().index()+1);
//index() returns index, add 1 because it starts from 0
$current.hide().next().show();
}
Fiddle here.

Just add a counter and change the html. Here is a Fiddle.
var counter = 1;
$("#counter").html("image "+counter+"/3");
$slides.click(function(){
// stores the currently-visible slide
var $current = $(this);
if( $current.is($slides.last()) ) {
$current.hide();
$slides.first().show();
counter = 1;
$("#counter").html("image "+counter+"/3");
}
// else, hide current slide and show the next one
else {
counter++;
$current.hide().next().show();
$("#counter").html("image "+counter+"/3");
}
});

thanks a lot.
I'll use the first option, #Hiral. I have another slideshow in my website and when trying the other options it's not working fine... but thanks a lot everyone !
I have another thing to fix. when I have 2 or 3 slideshow on my page, it doesn't work...
I'm using a repeater custom fields in my admin page, so I'm not able to know in advance how many slideshow I will need...
does anyone knows how I can fix it ?
here is a jsfiddle : http://jsfiddle.net/XRpeA/13/
<div id="slideframe">
<img class="image_news" src="http://s1.lemde.fr/image/2007/07/09/534x0/933544_5_aa6d_polynesie-bora-bora_0608bcead896ce3f59fc0e2fb3cc7435.jpg" />
<img class="image_news" src="http://production.slashmedias.com/main_images/images/000/005/357/IMAGE-PENSEE-HD-1_original_original_large.jpg?1372235419" />
<img class="image_news" src="http://images.telerama.fr/medias/2013/03/media_94814/une-image-un-film-l-auberge-de-dracula-1931,M106823.jpg" />
</div>
<br>
<div id="counter">image <span id="current">1</span> / <span id="total"></span></div>
<br><br>
<div id="slideframe">
<img class="image_news" src="http://s1.lemde.fr/image/2007/07/09/534x0/933544_5_aa6d_polynesie-bora-bora_0608bcead896ce3f59fc0e2fb3cc7435.jpg" />
<img class="image_news" src="http://production.slashmedias.com/main_images/images/000/005/357/IMAGE-PENSEE-HD-1_original_original_large.jpg?1372235419" />
<img class="image_news" src="http://images.telerama.fr/medias/2013/03/media_94814/une-image-un-film-l-auberge-de-dracula-1931,M106823.jpg" />
</div>
<br>
<div id="counter">image <span id="current">1</span> / <span id="total"></span></div>
thanks a lot

Give each image an id eg:1,2,3 and display the id when you are on that image.

Another option
// stores the currently-visible slide
var $current = $(this);
$current.hide();
if( $current.is($slides.last()) )
{
$current = $slides.first();
}
// else, hide current slide and show the next one
else
{
$current = $current.next();
}
$current.show();
$('#counter').text('image ' + ($slides.index($current) + 1) + ' / ' + $slides.length);
Plenty of options to choose from

Related

I can't get the animation speed to work

I'm trying to make a menu (with buttons) that open links.
when you hover on the buttons, a slideDown reveals more information on that link.
I've gotten all those features to technically work, however i can't get the animation speed to go any slower than instantly.
I'm really new to javascript and Jquery, and it took me 2-3 days to get the javascript and CSS to do what i have so far... and yeah it's probably bloated... but i'm still proud i got this done so far :D
PS, I know most menus are made w/ul's but I really like the way the buttons look and detested trying to put the list together. last time i tried used a seperate ul for the information and it kept styling the second list like the first because it was inside it... so annoying. I also tried vertical-link list w/CSS but still think flat 'buttons' are so boring. i really like the 3D esk of the actual html
HTML:
<div class="mainmenu">
<div id="homemenu">
<button id="home" class="mmbutton active">Home</button>
<div id="homesub" class="sub active">-just a bit about this page</div>
</div>
<div id="photosmenu">
<button id="photos" class="mmbutton">Photos</button>
<div id="photossub" class="sub inactive">-just a bit about this page
</div>
</div>
</div>
javascript/jquery:
$(function(){
var mmbutton = $('.mmbutton');
var start = "http://";
var address = "[my web address"; //add "http:
var about = "[web address]/aboutme.html";
var id = 0;
var rel = 0;
var mmsub = 0;
//<click link buttons:
$(mmbutton).click(function(){
var id = $(this).attr('id');
if (id === "home") {
location.replace(start+address);
}else if (id === "about") {
window.alert("I'm sorry I don't have this page set up yet. Thank you for visiting my page!");
//add additional buttons here under 'else if' unless its a subdomain
}else {
location.replace(start+id+'.'+address);//goes to any subdomain by id
}});
//>detect hover
$(mmbutton).hover(function(){
id = $(this).attr('id');
rel = '#'+id+'sub';
mmsub = '#'+id+'menu';
console.log('mouseenter'+rel);
$(rel).removeClass('inactive');
$(rel).stop().slideDown(500000);
}, function(){
console.log('mouseleave'+rel);
$(rel).addClass('inactive');
if ( $(this).hasClass('active')) {
$(rel).removeClass('inactive');
console.log('this is active');
}if ($(rel).hasClass('inactive')){
$(rel).stop().slideUp(500000);
}});});
relevante CSS:
.inactive {
display: none;
}
.sub {
transition-duration: 1s;
}
You can do it setting all that info divs to display:none and use slideToggle() function for that. Considering you want to keep the subdiv's opened when you're over them, one option is create a span element that include the button and the subdiv, and apply the hover to that span. So...
HTML:
<div class="mainmenu">
<div id="homemenu">
<span class="subcontainer">
<button id="home" class="mmbutton active">Home</button>
<div id="homesub" class="sub">-just a bit about this page</div>
</span>
</div>
<div id="photosmenu">
<span class="subcontainer">
<button id="photos" class="mmbutton">Photos</button>
<div id="photossub" class="sub">-just a bit about this page</div>
</span>
</div>
</div>
CSS:
.sub {
display: none;
/*transition-duration: 1s; IMPORTANT: REMOVE THIS!!*/
}
JQUERY:
$('span.subcontainer').hover(function() {
$(this).find('div.sub').slideToggle('slow');
});
IMPORTANT: Check that to make it work you have to remove the transition style you've created for .sub divs (it interfeers with the jquery function).
NOTE: I don't use the div.homemenu or div.photosmenu as the containers for the hover because div's normally have some styles pre-applied by default and can interfeer with the desired behaviour (for example, they normally have width=100% so the hover applies even when you're outside of the button or subdiv in the same line). span is normally more innocuous to use it just as a wrapper.
I hope it helps
Oh! i got it. i was trying to do too much (show off.../ using what im learning).
I removed the line that added and removed the class 'inactive' and just toggled the SlideUp and slideDown when i wanted it too. now i can adjust the animation speed:
(HTML remains unchanged)
CSS: removed the "transition-duration: 1s;"
JavaScript:
$(function(){
var mmbutton = $('.mmbutton');//any/all buttons
var activebut= 0; //detect button classes
var mmdiv = $("div[id$='menu']");//detect button sub info
var start = "http://";
var address = "[address]/index.html"; //add "http://" + [blog or games] + address
var about = "http://[address]/aboutme.html";
var id = 0;
var sub = 0;
var slidespeed= 450; //slideUP/slideDown animation speed //added var for speed
//<click link buttons: (unchanged)
$(mmbutton).click(function(){
id = $(this).attr('id');
if (id === "home") {
location.replace(start+address);
}else if (id === "about") {
location.replace(start+'[address]/aboutme/index.html')
//add additional buttons here under 'else if' unless its a subdomain
}else {
location.replace(start+id+'.'+address);//goes to any subdomain by id
}
});
//<hover display:
//<detect mouse ON button
$(mmbutton).hover(function(){
id = $(this).attr('id');
sub = '#'+id+'sub';
activebut= $(this);
if ( $(activebut).hasClass('active')) {
}else {
$(sub).stop().slideDown(slidespeed);
}
});
//<detect mouse off button AND div
$(mmdiv).mouseleave(function(){
if ( $(activebut).hasClass('active')) {
}else {
$(sub).stop().slideUp(slidespeed);
}
});
});

Updating text on a DIV causes it to update on the previous DIV's already clicked - jquery

I've been trying to solve this for the last couple of hours but all attempts failed...
What I need to do is to click on a DIV that will cause another DIV to pop up.
Inside the pop up there are some <li> and after clicking it, the attribute name is "transferred" to the first DIV clicked.
Ok, I managed to do that but after I update the first DIV and when I try to update the second DIV, the first DIV also gets updated and when I try to update the third DIV the other two gets updated ass well.
Can anyone help me to fix it and only update the DIV it was clicked on leaving the previous as it was supposed to be?
Here is the code:
HTML
<div class="num-1">
<img src="http://dummyimage.com/180x180/eeeeee/000000.jpg" width="180" height="180">
<p class="brand"></p>
<p class="name"></p>
</div>
<div class="num-2">
<img src="http://dummyimage.com/180x180/eeeeee/000000.jpg" width="180" height="180">
<p class="brand"></p>
<p class="name"></p>
</div>
<div class="num-3">
<img src="http://dummyimage.com/180x180/eeeeee/000000.jpg" width="180" height="180">
<p class="brand"></p>
<p class="name"></p>
</div>
<div class="num-4">
<img src="http://dummyimage.com/180x180/eeeeee/000000.jpg" width="180" height="180">
<p class="brand"></p>
<p class="name"></p>
</div>
<div class="num-5">
<img src="http://dummyimage.com/180x180/eeeeee/000000.jpg" width="180" height="180">
<p class="brand"></p>
<p class="name"></p>
</div>
<div class="popup">
<ul>
<li name="{{PHP GENERATED $name}}">{{PHP GENERATED $name}}</li>
<li name="{{PHP GENERATED $name}}">{{PHP GENERATED $name}}</li>
<li name="{{PHP GENERATED $name}}">{{PHP GENERATED $name}}</li>
</ul>
</div>
jQuery
//Openning the .popup and assigning the names
//First check the number of the div it was clicked on
$('img').on('click', function() {
var num = $(this).parent().attr('class').match(/\d+/)[0];
$('.popup').fadeIn();
//Click li to update the brand and name on the page
$('.popup li').on('click', function() {
//Check the name and split it
var nameComplete = $(this).attr('name');
var Array = nameComplete.split(" ");
//Check the first word and identify it as brand, also update on the page
var brand = Array[0];
$('.num-' + num + ' .brand').text(brand);
//Check the rest of the array for the name and update it on the page
var name = '';
for(var i=1; i<Array.length ;i++) {
name = name + Array[i] + ' ';
}
name = $.trim(name);
$('.num-' + num + ' .name').text(name);
$('.popup').fadeOut();
});
});
Someone might wonder if I'm getting the number of the DIV correctly.
I did console.log(num); and it shows that I'm clicking on the correct DIV because the DIV class is num-X (X = 1 to 5), 1 for 1, 2 for 2,...
The names of the <li> are ok, it works as it should, split it and get the right part to "transfer".
I guess I made the proper modifications to better understanding the code.
$('img').on('click', function() {
var num = $(this).parent().attr('class').match(/\d+/)[0];
window.num = num;
$('.popup').fadeIn();
});
//Click li to update the brand and name on the page
$('.popup li').on('click', function() {
//Check the name and split it
var nameComplete = $(this).attr('name');
var Array = nameComplete.split(" ");
//Check the first word and identify it as brand, also update on the page
var brand = Array[0];
$('.num-' + window.num + ' .brand').text(brand);
//Check the rest of the array for the name and update it on the page
var name = '';
for(var i=1; i<Array.length ;i++) {
name = name + Array[i] + ' ';
}
name = $.trim(name);
$('.num-' + num + ' .name').text(name);
$('.popup').fadeOut();
});
Separate both the click events in separate functions. Probably whats happening in your code is that every time you click on a div a new click event handler is attached to the '.popup li' and every time you click on one of the '.popup li' all the click handlers are activated. Thus explaining the multiple divs being updated.
Second option you have is to use jquery.off. This way every time you attach an event handle with .click to the '.popup li' you also remove it after you work is done and complete. Since this would have made your code harder to debug and to read i have preferred the first method in this answer.
NOTE**- i have changed the num to window.num which isnt a very good practice (keeping a global variable) but im sure you will be able to refactor the code once you get it to work

Can you do a loop to change array size depending on the number of photos in a file in javascript/php?

Sorry for the question isn't very clear, basically
I have got the php code to search for photos in the directory based on the userId given in the url. So if the userId = 1, it will go to Photos/1 and get all the photos in that directory and output it into an array that I can use in Javascript. It works.
I have an external javascript to my php/html code.
I am changing the attr of the div's to display the photos. I have 5 "photo containers" in the array called photodisplay:
var photodisplay =
[
$("#photo1"),
$("#photo2"),
$("#photo3"),
$("#photo4"),
$("#photo5"),
];
Then I have a loop to change the attribute/img src:
function preloadingPhotos() {
for (var x=0; x<galleryarray.length; x++)
{
photodisplay[x].attr("src", "Photos/" + userid + "/" + galleryarray[x]);
console.log("preloaded photos");
}
displayPhoto();
}
It works. Providing no more than 5 photos because that is how many photocontainers I have. But what if I had photos? The question is: Would I be able to do a loop to keep changing the photos in the photodisplay array?
I also have code for the photocontainers to fade in and out:
function displayPhoto(){
photodisplay[0].fadeIn(3000);
photodisplay[0].delay(3000).fadeOut(3000, function() { //first callback func
photodisplay[1].fadeIn(3000);
photodisplay[1].delay(3000).fadeOut(3000, function() { //second callback func
photodisplay[2].fadeIn(3000);
photodisplay[2].delay(3000).fadeOut(3000, function() { //third callback func
photodisplay[3].fadeIn(3000);
photodisplay[3].delay(3000).fadeOut(3000, function() { // fourth callback func
photodisplay[4].fadeIn(3000);
photodisplay[4].delay(3000).fadeOut(3000, function() {
setTimeout(displayPhoto(), 3000);
});
});
});
});
});
}// end of function displayPhoto
Which requires me to manually enter the number of the array of the photodisplay.
I would thinking of adding more to the array with duplications of the photocontainers. But I don't think that would work since I would have to manually enter the number of the array in the code above to make it fade in and out.
Sorry if this is confusing. I tried my best to explain my problem. I hope someone can help. Don't worry about the retrieving images in the directory part, because it works. It increases the array of photos accordingly, I just don't know how to adjust this change with my javascript.
The method you are using, does not scale as you have a callback function for every element in your slideshow.
What you should do, is put all images in a list (or a list of div's) and hide them all / change the z-index so that only the active one shows. The you can loop through your elements using .next() on the list items to get the next one (or the first one if .next().length is 0).
This will clean up your code and is pretty easy to do yourself but there are also loads of jQuery plugins that do it for you.
You need a little bit of abstraction here. So instead of manually code numbers, try another approach. For this example I've used jQuery; since you've tagged your question with it, I assume it's okay:
// Set a default value and store the current photo in it.
var currentPhoto = 0;
// Calculate the total number of photos
var photoTotal = photodisplay.length;
var photoTimeout = false;
// Create a function to go to the next photo
var nextPhoto = function () {
// Keep track of the new current
currentPhoto = (currentPhoto + 1) % photoTotal;
// Just to be sure clearTimeout
clearTimeout(photoTimeout);
// Fadein each photo; you might want to do something to reset the style
photodisplay[0].fadeIn({
duration: 3000,
complete: function () {
photoTimeout = setTimeout(nextPhoto, 3000);
}
});
}
nextPhoto();
You don't want to define JS from the backend like that; just have PHP render the markup, then use JS to query and parse the markup for the presentational layer.
Let's assume your markup looks like this:
<div id="photocontainers">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
<!-- A hidden array of images. -->
<div id="images">
<img src="http://placehold.it/100x100&text=1" />
<img src="http://placehold.it/100x100&text=2" />
<img src="http://placehold.it/100x100&text=3" />
<img src="http://placehold.it/100x100&text=4" />
<img src="http://placehold.it/100x100&text=5" />
<img src="http://placehold.it/100x100&text=6" />
<img src="http://placehold.it/100x100&text=7" />
<img src="http://placehold.it/100x100&text=8" />
<img src="http://placehold.it/100x100&text=9" />
<img src="http://placehold.it/100x100&text=10" />
<img src="http://placehold.it/100x100&text=11" />
</div>
So your server renders this; #images is just a hidden container, that basically preloads all the image assets you'll cycle between in #photocontainers.
var cycleImages = function() {
// Cache selectors that we'll need.
var $photoContainers = $('#photocontainers').children(),
$images = $('#images img'),
// Use `.data()` to get the starting point, or set to 0
// (if this is the first time the function ran).
startImage = $images.data('nextImage') || 0;
// Loop from the starting point, filling up the number of
// photocontainers in the DOM.
for (var i = startImage; i < startImage + $photoContainers.length; i++) {
var $targetImage = $images.eq(i % $images.length),
$targetPhotoContainer = $photoContainers.eq(i - startImage);
// Get rid of the current contents.
$targetPhotoContainer.empty();
// Clone the desired image, and append it into place.
$targetImage.clone().appendTo($targetPhotoContainer).fadeOut(0).fadeIn();
}
// Let's figure out which starting image is next up, and store that
// with `.data()`.
var nextImage = startImage + $photoContainers.length;
if (nextImage >= $images.length) {
nextImage -= $images.length;
}
$images.data('nextImage', nextImage);
}
// When the DOM is ready, call the method, then
// call it again however often you'd like.
$(document).ready(function() {
cycleImages();
setInterval(function() {
cycleImages();
}, 3000);
});
Here's a plunkr showing that in action: http://plnkr.co/SumqkXYpRXcOqEhAPOHm

setInterval method dilemma

I am trying to implement a slideshow using jQuery
I have a button called SlideShow and clicking it would trigger the slide show.
I display a set of thumbnails:
<div class="pics">
<img u="bob" id="pic1" src="/photos/thumbs/file1.jpg" class="apt" f="file1.jpg">
<img u="rob" id="pic2" src="/photos/thumbs/file2.jpg" class="apt" f="file2.jpg">
<img u="job" id="pic3" src="/photos/thumbs/file3.jpg" class="apt" f="file3.jpg">
<img u="tom" id="pic4" src="/photos/thumbs/file4.jpg" class="apt" f="file4.jpg">
<img u="scott" id="pic5" src="/photos/thumbs/file5.jpg" class="apt" f="file5.jpg">
</div>
You can see the thumbs has class 'apt' which will allow me to get the set of all thumbs.
The click event handler just need to call a function in a loop with a setInterval(f, 5000)
That way I read info of one thumb every 5 sec and load the full image from the server.
But I get undefined no matter how I do it. Here is the code:
var idx='';
function SlideShow() {
idx = 1; //global variable to track index of current thumb inside <div>
setInterval("GetFullImage()",5000);
}
function GetFullImage(){
var i = $('.apt:nth-child(' + idx + ')').attr("id");
var u = $('.apt:nth-child(' + idx + ')').attr("u");
var f = $('.apt:nth-child(' + idx + ')').attr("f");
alert('i:=' + i + ' u:' + u + ' f:' + f); <-- always say i, u, f undefined after first time
idx++;
}
What is wrong? I haven't played much with setInterval() calls.
You're referencing the nth-child not the sibling. The images are all siblings of each other, not one residing in the next. I would take it up a level, then use nth-child. or just grab:
$('.pics').children('img').length
as a threshold, then use:
$('.pics img:eq('+idx+')')
This way you keep upping idx until you've reached the limit, then reset the counter.
Try this, i.e. remove the speech marks and brackets from "GetFullImage()"
setInterval(GetFullImage,5000);

jQuery Carousel. How to show the Next or Previous Element only

I have a jQuery problem, and I've really tried everything I know (i am so newbie at this) so ..
The problem in short is I am doing a simple carousel-like effect. I am using this code.
(The div .showarea is the DIV which needs to be rotated (next/prev) but I want to keep only one div shown at a time.)
This is the html markup.
<div class="maincarousel">
<div class="showarea"><img src="img/sampleshow.png" alt="" title="" /></div>
<div class="showarea"><img src="img/sampleshow2.png" alt="" title="" /></div>
<div class="showarea"><img src="img/sampleshow3.png" alt="" title="" /></div>
</div>
This is my jquery attempt
$('.showarea').hide();
$('.showarea:first').fadeIn(500);
$('.maincarousel a').click(function () {
if ($(this).attr('href') == '#carouselNext') {
$('.showarea').hide();
$('.showarea').next('.showarea').fadeIn(500);
}
if ($(this).attr('href') == '#carouselPrev') {
$('.showarea').hide();
$('.showarea').prev('.showarea').fadeIn(500);
}
});
Unfortunately, next() and prev() won't display the next element only, but all next elements and same thing for prev(). Any quick workaround..
Can someone help me on this,
Thanks
You could try using .eq(0) to select the first element in the collection given to you by .prev() and .next().
Note that .next() and .prev(), like most jQuery methods, are operating on a collection. So if your selector '.showarea' is selecting multiple elements, then .next() will select the next sibling element for each element selected by '.showarea', and similarly for .prev().
if ($(this).attr('href') == '#carouselNext') {
$('.showarea').hide();
var el = $('.showarea').next('.showarea').eq(0);
if (el.length) {
el.fadeIn(500);
}
}
if ($(this).attr('href') == '#carouselPrev') {
$('.showarea').hide();
var el = $('.showarea').prev('.showarea').eq(0);
if (el.length) {
el.fadeIn(500);
}
}
The below will rotate so if you are at the first item pressing back will then show the last item...
Demo here
$('div.showarea').fadeOut(0);
$('div.showarea:first').fadeIn(500);
$('a.leftarrow, a.rightarrow').click( function (ev) {
//prevent browser jumping to top
ev.preventDefault();
//get current visible item
var $visibleItem = $('div.showarea:visible');
//get total item count
var total = $('div.showarea').length;
//get index of current visible item
var index = $visibleItem.prevAll().length;
//if we click next increment current index, else decrease index
$(this).attr('href') === '#carouselNext' ? index++ : index--;
//if we are now past the beginning or end show the last or first item
if (index === -1){
index = total-1;
}
if (index === total){
index = 0
}
//hide current show item
$visibleItem.hide();
//fade in the relevant item
$('div.showarea:eq(' + index + ')').fadeIn(500);
});

Categories