Why is my image slideshow not working? - javascript

I'm programming an image slideshow and for some reason it isn't working. Below I have the HTML:
<div id = "images">
<img id = "imageSrc" />
</div>
Here is my JavaScript which is what I'm using to change my images:
var images = document.getElementById("imageSrc");
var x = 0;
var imagesArray = ["image.png", "anotherImage.png", "yetAnotherImage.png"];
function changeImages() {
images.src = imagesArray[x];
if (x < 2) {
x++;
} else {
x = 0;
}
alert(images.src);
}
setInterval(changeImages(), 3000);
Demo
Why am I not getting an alert every 3 seconds with my image code? The images aren't switching so where is my mistake?
Thanks in advance for your help!

When calling a function as an argument, don't use parentheses.
setInterval(changeImages, 3000);
Demo
If you did need to pass arguments in the function call, wrap it in an anonymous function:
setInterval(function() {
var myArg;
changeImages(myArg);
}, 3000);
Demo

Remove the curly braces when you are calling the function
Change
setInterval(changeImages(), 3000);
to
setInterval(changeImages, 3000);

Related

setTimeout, JavaScript, no effect

I need to animate something, but my statement has no effect. My code:
var movei=function(img){
img.setAttribute("src", "blank.png");
}
var comp=function() {
...
for(var k=0; k<i; k++) {
var img=document.getElementById(id(k,col));
img.setAttribute("src", "circ1.png");
timer=setTimeout(movei(img),1000);
...
}
}
I read another questions about setTimeout (setInterval) but I couldn`t find an answer.
try timer=setTimeout(function(){movei(img);},1000);
If you want to animate individual elements, you should use recursion instead of loops.
Following code depicts the same:
var count = 0;
function getId(count) {
return "div_" + count;
}
function initTimer() {
setTimeout(function() {
count++;
var _id = getId(count);
var _el = document.getElementById(_id);
show(_el);
if (count < 7)
initTimer();
}, 1000);
}
function show(el) {
el.style.display = "block";
}
initTimer();
div {
display: none;
}
<div id="div_1">1</div>
<div id="div_2">2</div>
<div id="div_3">3</div>
<div id="div_4">4</div>
<div id="div_5">5</div>
<div id="div_6">6</div>
As #deceze has also written, you need to change the call to setTimeout so that you do not call the movei function, but rather pass the function 'name'. Then you would of cause have to change the behavior the function movei so it either gets a simple string name of the image or can lookup the image itself.
timer=setTimeout(movei,1000);
or (in the not recommented way)
timer=setTimeout("movei(\"imgName\")",1000);

Why is Javascript function not being called?

First Question on this site so I hope I do this right! I have a javascript function that I want to display an image (image1.jpg) when the page is loaded, and then every 2 seconds change the image by going through the loop. However only the first image is showing so it seems the JS function is not being called. Can anyone tell me if I am doing something wrong here because it looks fine to me so can't understand why it won't work. Thanks
<html>
<head>
<script type="text/javascript">
function displayImages(){
var images = ['image1.jpg', 'image2.jpg', 'image3.jpg'];
var i = 1;
if(i>images.length-1){
this.src=images[0];
i=1;
}else{
this.src=images[i];
i++;
}
setTimeout("displayImages()", 2000);
}
</script>
</head>
<body onload="displayImages();">
<img id="myButton" src="image1.jpg" />
</body>
</html>
You need to move the line
var i = 1;
outside the displayImages -function or it will start from one each time!
EDIT: But using a global variable is not considered good practice, so you could use closures instead. Also as noted in other answers, you are referencing this which does not refer to the image object, so I corrected that as well as simplified the logic a bit:
<script type="text/javascript">
function displayImages( i ){
var images = ['image1.jpg', 'image2.jpg', 'image3.jpg'];
var img = document.getElementById('myButton');
img.src = images[i];
i = (i+1) % images.length;
setTimeout( function() { displayImages(i); }, 2000 );
}
</script>
<body onload="displayImages(0);">
You need the value of i to be available at each call, it can be kept in a closure using something like:
var displayImages = (function() {
var i = 0;
var images = ['image1.jpg', 'image2.jpg', 'image3.jpg'];
return function() {
document.getElementById('myButton').src = images[i++ % images.length];
setTimeout(displayImages, 2000);
}
}());
Also, since this isn't set by the call, it will default to the global/window object, so you need to get a reference to the image. That too could be held in a closure.
There are a couple of issues here that are stopping this from working.
First the var i = 1; needs to be moved outside the function to make the increment work. Also note that the first item in an array is 0, not 1.
Second you're using this to refer to change the image's src, but this is not a reference to the image. The best thing to do is use here is document.getElementById instead.
var i, button;
i = 0;
button = document.getElementById('myButton');
function displayImages() {
var images = ['image1.jpg', 'image2.jpg', 'image3.jpg'];
if (i > images.length - 1){
button.src = images[0];
i = 0;
}
else{
button.src = images[i];
i++;
}
setTimeout(displayImages, 2000);
}
There's still some room for improvement and optimisation, but this should work.
You are reinitializing value of i every time, so change the following:
function displayImages(){
var images = ['image1.jpg', 'image2.jpg', 'image3.jpg'];
if(!displayImages.i || displayImages.i >= images.length) displayImages.i = 0;
document.getElementById('myButton').src = images[displayImages.i];
displayImages.i++;
setTimeout(displayImages, 2000);
}
Functions are objects in JS and because of this:
you can pass them by reference and not as a string improving performance and readability
you can add fields and even methods to a function object like I did with displayImages.i
EDIT: I've realized that there was one more issue src was not being set for button.
Now I've fixed this and also made other improvements.
Here is the fiddle http://jsfiddle.net/aD4Kj/3/ Only image URLs changed to actually show something.
<script type="text/javascript">
var i = 1;
function displayImages(){
.......
........
Just make "i" Global. so that whenever displayImages being called it will not redefined to 1.
<html>
<head>
<script type="text/javascript">
var i = 1;
function displayImages() {
var images = ['img1.jpg', 'img2.jpg', 'img3.jpg'];
i++;
if (i > images.length - 1) {
i = 0;
}
$('#myButton').attr('src', images[i]);
setTimeout(displayImages, 2000);
}
</script></head>
<body onload="displayImages();">
<img id="myButton" src="img1.jpg" height="150px" width="150px"/>
</body>
</html>
Make i global.
here your are using displayImages() recursively and variable for index i. e i assign as local variable in function displayImages() , you need to assign it global variable i.e outside of the function also initialize it from i=0 as array index always start from 0,
your code become
var i = 0; // assign i global
function displayImages(){
var images = ['image1.jpg', 'image2.jpg', 'image3.jpg'];
if(i>images.length-1){
document.getElementById('myButton').src=images[0]; //get img by id
i=0; // to get first image
}
else{
document.getElementById('myButton').src=images[i]; //get img by id
i++;
}
setTimeout("displayImages()", 2000);
}

JQuery - function change images automatically

I need, that some images (for example random 5 - 8 of them) on background will automatically change for another one image (for example after 10 sec, something like that example-link but automatically, not on hover).
$('.fader').hover(function() {
$(this).find("img").fadeToggle();
});
I made a JSFiddle DEMO.. Maybe it helps you.
It's pretty simple, that's the function that I execute in setInterval
var $imgs = $(".fader").find("img"),
i = 0;
function changeImage(){
var next = (++i % $imgs.length);
$($imgs.get(next - 1)).fadeOut(500);
$($imgs.get(next)).fadeIn(500);
}
var interval = setInterval(changeImage, 2000);
Hope it help..
You can use setInterval to run a function every so often, then inside it have your image changing function
//global variable
var bgImg = 1;
//runs every second
window.setInterval(function(){
yourFunction();
}, 10000);
//changes background image
function yourFunction () {
++bgImg;
if(bgImg === 4){
bgImg = 1;
}
if(bgImg === 1){
$('#element').css("background-image","URL('imgs/image1.jpg')");
}
if(bgImg === 2){
$('#element').css("background-image","URL('imgs/image3.jpg')");
}
if(bgImg === 3){
$('#element').css("background-image","URL('imgs/image3.jpg')");
}
}
You can always add some more jquery to fade the image in out or something smoother than a plain switch
is this what you want?
Use BX slider.
http://jsfiddle.net/writetobhuwan/Xm2Be/393/
JS is as simple as this..
$(document).ready(function(){
$('.bxslider').bxSlider();
});

How to create a rotating thumbnails functionality in jQuery?

Basically I need the thumbnails to rotate every time the user hovers over an image. Here is my failed attempt:
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
<script type="text/javascript">
$(function() {
$('img').hover(function() {
theImage = $(this).attr('id');
otherImages = $(this).attr('class').split('#');
rotateThumbs(otherImages, theImage);
}, function() {
//
});
});
function rotateThumbs(otherImages, theImage) {
for (i=0; i < otherImages.length; i++) {
setInterval($('#'+theImage).attr('src', otherImages[i]), 1000);
}
}
</script>
<img id="myImage" src="http://www.google.com/images/logos/ps_logo2.png" class="http://www.google.com/images/logos/ps_logo2.png#http://l.yimg.com/a/i/ww/met/yahoo_logo_us_061509.png#http://dogandcat.com/images/cat2.jpg" width="174" height="130" />
Does anyone know how this may be accomplished?
Some issues here.
setInterval requires a function reference as it's first argument, but you are executing code that returns a jQuery object.
setInterval executes the first function repeatedly at the specified interval. Is that what you are trying to do? Swap images every second?
Depending on how you correct the first issue, you could run into an issue where i is otherImages.length and thus the src is set to undefined.
Assuming you worked around issue 3, you will have the problem that the image swaps will happen imperceptibly fast and it will appear as though the last image is always displayed.
Instead, don't use a loop. Increment a counter each time a new image is displayed. Try this:
function rotateThumbs(otherImages, theImage) {
var i = 0;
var interval = setInterval(function() {
$('#'+theImage).attr('src', otherImages[i++]);
if (i >= otherImages.length) {
clearInterval(interval);
}
}, 1000);
}
I've implemented a fully-functional example here. This addresses some of the issues that #gilly3 notes, but uses closures instead of an incrementing counter to keep track of the current image:
$(function() {
$('img').hover(function() {
// declaring these variables here will preserve
// the references in the function called by setInterval
var $img = $(this),
imageList = $img.attr('class').split('#'),
intervalId;
// start the cycle
intervalId = window.setInterval(function() {
var next = imageList.pop();
if (next) {
$img.attr('src', next);
} else {
// stop the cycle
intervalId = window.clearInterval(intervalId);
}
}, 1000);
}, function() {});
});
As you can see, using a closure is much easier when you declare the function passed to setInterval inline, rather than as a separate, named function. You could still have a rotateThumbs function if you wanted, but you might need to do some more work to ensure that the variables were being passed properly.
Edit: I made an updated version that continues to cycle as long as the mouse is hovering.
I have adjusted the answer for Sam, taking pre-loading the image into account, so that you won't have a possible deplay at the first rotation.
function rotateThumbs(otherImages, theImage) {
if(!$('#'+theImage).data('setup')){
$('#'+theImage).data('setup', true); // do not double pre-loading images
var $body = $('body');
for(var j = 0; j < otherImages.length; j++){
$body.append($('<img/>').attr('src', otherImages[j])
.css('display', 'none'));
}
}
var i= 0;
setInterval(function(){
$('#'+theImage).attr('src', otherImages[i++]);
if(i >= otherImages.length){i = 0}
}, 1000);
}

How to use .html() with a timer in jQuery?

I want to replace the contents of a div with the values found in an array. I want to keep each value within the div for 3 seconds each. Here's my code so far:
var images = ['a.jpg', 'b.jpg', 'c.jpg'];
for (i = 0; i < images.length; i++) {
$('#slideShow').html("<img src='../"+images[i]+"' alt='' />");
}
This of course changes the images so fast that the human eye only sees one image being in the div at all times. I want to keep each image for 3 seconds before the next .html() is done on the div. How to do this?
Try this:
images = ["a.jpg", "b.jpg", "c.jpg"];
function change(i){
if(!images[i]){return false}
else{
$("#slideShow").src=images[i];
setTimeout( function(){ change(i+1) }, 3000);
}
}
change(0);
Haven't tested it but it should work.
This answer assumes that you want to loop. If not, comment and I'll rewrite.
<script>
var images = ['a.jpg', 'b.jpg', 'c.jpg'];
var curimage = 0;
function changeImage() {
$('#slideShow').html("<img src='../"+images[curimage]+"' alt='' />");
curimage++;
if (curimage > images.length) curimage = 0;
}
changeImage();
window.setInterval(changeImage, 3000);
</script>
I have tested this answer.

Categories