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);
Related
I have some code, http://jsfiddle.net/hucw940s/
which has a for loop.
before
<div id="container">
</div>
after
for (i = 1; i < 4; i++){
var showMe = $('<a href=# id="link' + i + '">')
.append('click').click(function(){ alert('You clicked num: ' + i) });
$('#container').append(
$('<div id="div'+i+'">').append('this is div number: ' + i).append(showMe)
);
}
so the links are generated with id=link1, link2, link3 etc, and the divs appended are the same, however the onclick code seems to put the var i in after the event, so on clicking any link they say "you clicked number 4"
How can I make this use the i from the clicked link inside the function that is called on click?
What you are experiencing is the expected behavior based on your code.
However, what you are actually trying to do is pass in event data to your click function. This can be accomplished like this:
for (i = 1; i < 4; i++) {
var showMe = $('<a href=# id="link' + i + '">').append('click')
.click({value: i}, function (e) { alert('You clicked num: ' + e.data.value) });
$('#container').append($('<div id="div' + i + '">').append('this is div number: ' + i).append(showMe));
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="container">
</div>
First, you have to assign the event data, so we pass in an object
{value: i} before we pass in the handler function.
Then, in the handler function, we assign the variable e to the
event, so we can access the data attribute.
Finally, you access the value that was passed in by referencing
e.data.value.
You can add as many event data objects as you want and reference them by name this way.
The reason your code is not working as you are expecting is because the variable i is already equal to 3 by the time the click event happens, since the for loop completes before you are able to click any of the links.
Hope this helps give you a better understanding of why your code is behaving the way it is and what you can do to fix it.
Store the id in a data-attribute.
Updated jsFiddle
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
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
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
I'm trying to define a variable on a mouseover event.
The idea is that I can later use that variable to replace the DIV ID's, and "swap-image" pahts to create a generic mouseover script that I can use for a bunch of buttons.
So I don't have to use the same code over and over again and only swich out a few numbers.
Would this work? I tried something like this:
//define variable on mouseover
$("#world_map_8_button").mouseover(function() {
var location = "#world_map_8";
});
//use variable within script
//mouse over/out swap image +
$(location + "_button").hover(function() {
$(location + "_button_jpg").attr("src", "img/buttons/map_buttons/world_map/world_map_8_button_over.jpg");
}, function() {
$(location + "_button_jpg").attr("src", "img/buttons/map_buttons/world_map/world_map_8_button.jpg");
});
});
This is some of the html code to help things clear up, all buttons are named the same way.
<div id="world_map_8_button">
<img id="world_map_8_button_jpg" src="img/buttons/map_buttons/world_map/world_map_8_button.jpg" width="41" height="41" alt="" />
</div>
<div id="world_map_9_button">
<img id="world_map_9_button_jpg" src="img/buttons/map_buttons/world_map/world_map_9_button.jpg" width="41" height="41" alt="" />
</div>
<div id="world_map_10_button">
<img id="world_map_10_button_jpg" src="img/buttons/map_buttons/world_map/world_map_10_button.jpg" width="41" height="41" alt="" />
</div>
if I declare the variable in the HOVER function it works (only for the mouseon though) but that doesn't make any sense and wouldn't be labour saving...
$("#world_map_8_button").hover(function() {
var location = "#world_map_8";
$((location + "_button_jpg")).attr("src", "img/buttons/map_buttons/world_map/world_map_8_button_over.jpg");
},
function() {
$((location + "_button_jpg")).attr("src", "img/buttons/map_buttons/world_map/world_map_8_button.jpg");
});
Looking at your code I think attribute ends with selector $= will help you. You don't have to set any variable to do this, try this
$("[id$=_button]").hover(function() {
$("#" + this.id + "_jpg").attr("src", "img/buttons/map_buttons/world_map/" + this.id + "_button_over.jpg");
}, function() {
$"#" + this.id + "_jpg").attr("src", "img/buttons/map_buttons/world_map/" + this.id + "_button.jpg");
});
});
This is a good candidate for CSS. You could have one image with both the hover and normal images in, and then set the background offset when the mouse hovers. W3Schools explains the technique well
To answer your question directly, however, you could try something like this:
$('[id$=_button]').hover(function() {
$('#'+this.id+'_jpg').attr('src', 'img/buttons/map_buttons/world_map/' + this.id + '_over.jpg');
}, function () {
$('#'+this.id+'_jpg').attr('src', 'img/buttons/map_buttons/world_map/' + this.id + '.jpg');
});
You would only have to put this on your page to take care of it all without having multiple scripts and global variable declarations.
No that won't work. Use jQuery's .data(); method.