Carousel of Images Will Not Advance (HTML/JavaScript) - javascript

I am attempting to have the carousel start immediately upon visiting the page and cycle through a series of images every 2.5 seconds, however it will not advance past the first image. I've looked around here and w3schools but haven't been able to locate where my issue is. Any help would be greatly appreciated!
JavaScript is as follows:
window.onload slideShow();
var i=0;
function slideShow() {
window.setInterval("nextSlide()", 2500);
}
function nextSlide() {
var images["images/stockton0.jpg",
"images/stockton1.jpg"
"images/stockton2.jpg"
"images/stockton3.jpg"
"images/stockton4.jpg"
"images/stockton5.jpg"
"images/stockton6.jpg"
"images/stockton7.jpg"
"images/stockton8.jpg"
"images/stockton9.jpg"
"images/stockton10.jpg"]
var photo = document.getElementByClass("stocktonPics");
photo.src = images[i];
i++;
}
HTML code:
<img class="stocktonPics" src="images/stockton0.jpg" alt="slides">

A good tip is to check the console for errors.
There's nothing wrong with the flow of your code, besides some tips on making it more maintainable, readable, or semantically correct.
You simply forgot an = in window.onload = slideShow;
And document.getElementByClass doesn't exist. You need to use document.getElementsByClassName(...) to get an array of elements with that class, and finally get its first item with [0] like so:
var photo = document.getElementsByClassName("stocktonPics")[0];
Note that slideShow no longer has the () to call it, when window.onload is assigned to it. This is because you're assigning window.onload to the slideShow function, not the result of calling slideShow(), which in this case is undefined, as nothing is returned.
Your image array should be assigned in this way: var images = [ a, b, c ]
The other thing you should do is keep the array of images outside the scope of the function, so you can use it more easily and change it, rather than creating one (if you don't count optimizations) ever time the function is called. And lastly, window.setInterval( a, b ) can take either a string that will be eval()ed (or equivalent to it), which is what you did, or a function itself. In your case, what you want is simply the function: window.setInterval( nextSlide, 2500 ).
Here's the final full code:
var i=0;
var images=[
"images/stockton0.jpg",
"images/stockton1.jpg",
"images/stockton2.jpg",
"images/stockton3.jpg",
"images/stockton4.jpg",
"images/stockton5.jpg",
"images/stockton6.jpg",
"images/stockton7.jpg",
"images/stockton8.jpg",
"images/stockton9.jpg",
"images/stockton10.jpg" ];
function slideShow() {
window.setInterval( nextSlide, 2500);
}
function nextSlide() {
var photo = document.getElementsByClassName("stocktonPics")[0];
photo.src = images[i];
i++;
}
window.onload = slideShow;

getElementsByClass
method is will get a like array elements object,
so, you should use [0] to get the first element object and set src attr.
var pics = document.getElementsByClassName("stocktonPics")
It's a like array elements object
var firstPic = document.getElementsByClassName("stocktonPics")[0]
It's a element object
let i = 0;
const images = ["images/stockton0.jpg",
"images/stockton1.jpg",
"images/stockton2.jpg",
"images/stockton3.jpg",
"images/stockton4.jpg",
"images/stockton5.jpg",
"images/stockton6.jpg",
"images/stockton7.jpg",
"images/stockton8.jpg",
"images/stockton9.jpg",
"images/stockton10.jpg"];
const stockton = document.getElementsByClassName("example")[0];
const slideShow = () => {
window.setInterval(nextSlide, 2500);
}
const nextSlide = () => {
stockton.src = images[i];
if(i >= images.length - 1) {
i = 0;
} else {
i++;
}
console.log(i, stockton)
}
slideShow()
<img class="example">

Related

Use JS to change the source of an image element after loading the image?

Is it possible to use JS (specifically with the p5 library) to change the source of an image element? I was trying to make a very low-level slideshow on my webpage and I thought I could just do something like this (the code is also in the picture below):
let slide;
function setup() {
let sliders = ['cap_1.jpg', 'cap_2.jpg', 'spidermen.jpg'];
let i = 0;
slide = createImg(sliders[0], 'An image of Steve Rogers');
slide.parent('container');
slide.class('images');
setInterval(changeImg, 2000);
}
const changeImg = () => {
slide.src = (sliders[1])
}
The "sliders" variable isn't available to the "changeImg" function because it's in the "setup" function's scope. Try something like
let slide;
function setup() {
let sliders = ['cap_1.jpg', 'cap_2.jpg', 'spidermen.jpg'];
// I don't know anything about the p5 library, so I'm assuming
// all of the code below runs (i.e. createImg() returns an HTML img element); if not, look into functions like
// document.createElement(), because it's not always
// straightforward or obvious how to change certain element
// attributes like classes and parents
slide = createImg(sliders[0], 'An image of Steve Rogers');
slide.parent('container');
slide.class('images');
setInterval(() => changeImg(sliders[1]), 2000);
}
const changeImg = (targetUrl) => {
slide.src = targetUrl;
}
There are a few issues:
in your changeImg() you are only using index 1 from the array, it never advances to the next image.
because changeImg() is in different scope from setup(), it won't have access to variables created inside setup() function, so neither sliders nor i are accessible.
Once the slideshow started, there is no way to stop it.
function setup() {
let sliders = ['https://lh3.googleusercontent.com/taykG37GWDgY-FGkdogDvsHSJMUGRMvkuVRT6yR-5UNkKvGRKeRlpGYXlslocOcS0txlfUdGW59JGtzADknxbMqnh6AtVCv9EXyB8nHp80YsRNA0Yw=w102-h68-n-l50-sg-rj', 'https://lh3.googleusercontent.com/9pPCK70Rw0k3wethMHb1qMaIB0VjeWLy57vYgSzKbF7oJuvO2nA0Nakk-95cvibWUDcEhYkfCKvdPKT03tXZd4M5jdhIEibLO9qw-XE=w102-h68-n-l50-sg-rj', 'https://lh3.googleusercontent.com/fl-GT6w3Ls6RT4vYnbkuYUyLY3lZJH8VtZ7xzxiym9YYaoVRCnZehdz6Icd0oAf6i3H9-O5cCNs6eunlxWr_Csstgsb98DdzNdLFBOlhw9NUfHdyuQjI=w76-h102-n-l50-sg-rj'];
let i = 0;
/*
let slide = createImg(sliders[0], 'An image of Steve Rogers');
slide.parent('container');
slide.class('images');
*/
let slide = document.createElement("img");
slide.src = sliders[0];
slide.title = 'An image of Steve Rogers';
slide.className = "images";
document.body.appendChild(slide);
const changeImg = () => {
slide.src = sliders[++i % sliders.length];
}
return setInterval(changeImg, 2000);
}
let interval = setup(); //clearInterval(interval) to stop the slideshow

How to preload images for a game in the simplest way possible? (pure js, no library)

I want to have game.js which will only start execution when all the necessary images have been preloaded. The best way I can think of is something like:
var numberOfImagesToPreload = 2;
var imgsLoadedSoFar = 0;
var sources = ['player.png', 'terrain.png'];
for(let i = 0; i < sources.length; i++) {
var anImage = new Image();
anImage.src = sources[i];
anImage.onload = function() {
imgsLoadedSoFar++;
}
};
console.log(imgsLoadedSoFar);
if(imgsLoadedSoFar === numberOfImagesToPreload) {
console.log("Done, now start executing game.js");
};
Clearly this doesn't work because of async problems and I want to have preloader.js that will load the images first and then I want to launch game.js in which each image(game object) will have update and draw methods. If you think this shouldn't be done that way please suggest how. Thanks a lot.
EDIT
I am making some progress on this. Once the preloader.js loads all the resources I call a function in game.js function(image) but still not what I am looking for, which is basically once game.js starts loaded ALL the images should be loaded already.
Move the if inside your loop?
for(let i = 0; i < sources.length; i++) {
var anImage = new Image();
anImage.src = sources[i];
anImage.onload = function() {
imgsLoadedSoFar++;
if(imgsLoadedSoFar === numberOfImagesToPreload) {
console.log("Done, now start executing game.js");
};
}
};
Add a global boolean variable to switch to true only after preloading, wrap the functions on game.js in an if statement, once the boolean becomes true make call the function in game.js

How to Autorun an onclick event

sorry am still learning JavaScript, read W3Cschools javascript and Jquery but there is a lot they don't teach.
I am studying animation at the moment, how do I auto start this rather then wait for someone to click (event listener), I've attempted turning it into a function but I must be doing it wrong, also 1 more what does (Idx) mean, I understand (id) is Html ID element but not sure Idx, not easy to find on google. to read, event listener starts at 5th line from the bottom, and the shuffle cards is 6th line from top (not sure if that helps), original code is located here http://www.the-art-of-web.com/javascript/css-animation/ thanks for any help.
Regards. William.
var cardClick = function(id)
{
if(started) {
showCard(id);
} else {
// shuffle and deal cards
card_value.sort(function() { return Math.round(Math.random()) - 0.5; });
for(i=0; i < 16; i++) {
(function(idx) {
setTimeout(function() { moveToPlace(idx); }, idx * 100);
})(i);
}
started = true;
}
};
// initialise
var stage = document.getElementById(targetId);
var felt = document.createElement("div");
felt.id = "felt";
stage.appendChild(felt);
// template for card
var card = document.createElement("div");
card.innerHTML = "<img src=\"/images/cards/back.png\">";
for(var i=0; i < 16; i++) {
var newCard = card.cloneNode(true);
newCard.fromtop = 15 + 120 * Math.floor(i/4);
newCard.fromleft = 70 + 100 * (i%4);
(function(idx) {
newCard.addEventListener("click", function() { cardClick(idx); }, false);
})(i);
felt.appendChild(newCard);
cards.push(newCard);
I've gone through your code and added comments to try and help explain what is going on in this file:
//Declare card click function. Takes one parameter (id)
var cardClick = function(id){
if(started) {
showCard(id);
} else {
// shuffle and deal cards
card_value.sort(function() {
return Math.round(Math.random()) - 0.5;
});
for(i=0; i < 16; i++) {
(function(idx) {
setTimeout(function() {
moveToPlace(idx);
}, idx * 100);
})(i);
}
started = true;
}
};
// initialise
//set stage as reference to some element
var stage = document.getElementById(targetId);
//append a div with ID "felt" to the stage element
var felt = document.createElement("div");
felt.id = "felt";
stage.appendChild(felt);
// template for card
//declare card variable as a div with some html content
var card = document.createElement("div");
card.innerHTML = "<img src=\"/images/cards/back.png\">";
//Loop from 0 to 16, where i = current value
for(var i=0; i < 16; i++) {
//create a copy of the card made earlier
var newCard = card.cloneNode(true);
//apply some attributes to the new card
newCard.fromtop = 15 + 120 * Math.floor(i/4);
newCard.fromleft = 70 + 100 * (i%4);
//Create and run an anonymous function.
//The function takes one parameter (idx)
//The function is called using (i) as (idx)
(function(idx) {
//add click handler to the card element that triggers the card click
//function with parameter (idx)
newCard.addEventListener("click", function() { cardClick(idx); }, false);
})(i);
//add new card to the stage
felt.appendChild(newCard);
//add new card to an array of cards
cards.push(newCard);
} //end for loop (I added this. It should be here)
how do I auto start this rather then wait for someone to click
The way I would do it, is add a manual click event after the for loop that targets the first card that has the event handler. Because there is no ID set on the cards, I would try using the array that the cards are added to. Assuming that the cards array was empty when we started:
cards[0].click();
If that doesn't work, I would try targeting the item in the DOM. We know that each card is added to the end of div#felt. So, if we can target the first div inside felt, we should be able to trigger the click event on it.
document.getElementByID("felt").firstChild.click();
what does (Idx) mean
I'm hoping the comments help explain this. It looks like the variable idx is just used as an extended reference of i. Inside a for loop, the writer creates a function that takes one parameter (idx). The for loop has a variable (i) that increases by one for each instance of the loop. Each time the loop happens, i is passed into function as idx.
I hope that helps to get you an understanding of how this code works.

Why this javascript does not work?

I am having some trouble with this code, I tested it online but it doesn't seem to work. This is all of my coding:
My HTML:
<img src="kruisje.jpg" id="image1">
And the script that SHOULD make it a slideshow but doesn't:
var img = document.getElementById("image1").src;
function changeimage(){
wait(10)
for(var i = 0; i < images.length; i++){
return img
}
}
var images = ["","","","","",""]
And I know the links in the array aren't filled in but I have the links for it ready. They are just pictures so you can fill in any url you want if you are testing it.
Can somebody say me what i am doing wrong on this code?
Depending on when you run it, document.getElementById("image1") may return an element or null. If it returns null the script will error when you try to access the src property and abort.
You never call the changeimage function
There is no wait function in JavaScript and you don't appear to have defined one.
You return img, so you exit the function on the first time you go around the loop
If you wanted to assign a new URL to img then you would just be assigning the URL to the variable. img will be a variable containing a string. It won't reference the src property.
If you want to do this, you need to completely change your approach.
// Get a reference to the element (make sure you run this *after* the image has been added to the DOM)
var img = document.getElementById("image1");
// Track where you are in the array
var imagesIndex = 0;
var images = ["","","","","",""]
function changeImage(){
// Assign the new URL to the src property of the image
img.src = images[imagesIndex];
// Increment the index here
imageIndex++;
// Check if it has gone off the end and reset it if it has
if (imageIndex >= images.length) {
imageIndex = 0;
}
}
// Call the function on your time period
setInterval(changeImage, 10000);
var img = document.getElementById("image1").src;
function changeimage(){
wait(10) // ERROR FUNCTION
setTimeout(function(){alert("Hello")},3000);
for(var i = 0; i < images.length; i++){
return img
}
}
var images = ["","","","","",""]
you need use setTimeout(function(){alert("Hello")},3000);

Javascript: How do I get the height of unloaded images in a loop?

I am loading a json file and parsing it into an array in Javascript. One of the elements is the path to an image. I am not ready to load the images yet but I need to get the image's height. I know how to do that with code like the following (found on other stackoverflow pages)
function getimageheight(img) {
var tmpImg = new Image();
tmpImg.onload = function() {
var ht = this.height;
return ht+0;
}
tmpImg.src = img;
}
If I try to call this function in a loop, it returns undefined because the onload for the images is running slower than the loop. My actual code is this:
var j = 0;
$.each(cat.placemarks, function(index, mark) {
markers[cat.name][j] = [];
markers[cat.name][j].name = mark.name;
markers[cat.name][j].title = mark.title;
markers[cat.name][j].markerURL = mark.markerURL;
markers[cat.name][j].imageURL = mark.imageURL;
markers[cat.name][j].imageHEIGHT = getimageheight(projpath+mark.imageURL);
j++;
});
If I call the function once, it works. But calling it in a loop does not. How can I fix this?
If you store reference to data object in Img object used to load it, you can set the value of its properties after the loading is done. Hope that makes sense... Your data will not be ready to use before loading is complete tho. Heres the code
var total=cat.placemarks.length;//if an array, otherwise use another each cycle to get object count
var loaded=0;
$each(cat.placemarks, function(index, mark) {
markers[cat.name][j] = [];
var tmpImg = new Image();
tmpImg.refToObjWithNameOfYourChoice=markers[cat.name][j];
tmpImg.onload = function() {
this.refToObjWithNameOfYourChoice.imageHEIGHT=this.heigh;
loaded++;
if(loaded==total){
//markers data is ready to use - add function callback herer or sumthin'
}
}
tmpImg.src=projpath+mark.imageURL;
markers[cat.name][j].name = mark.name;
markers[cat.name][j].title = mark.title;
markers[cat.name][j].markerURL = mark.markerURL;
markers[cat.name][j].imageURL = mark.imageURL;
j++;
});
markers[cat.name][j].imageHEIGHT is undefined because getImageHeight() isn't returning anything. And naturally, the image load will occur much more slowly than your each() loop, so it won't do you any good to have getImageHeight() return something. You'll have to set up your load() callback to determine which image has been loaded and update the height of the corresponding markers element.

Categories