Changing image to another on click - javascript

We are currently creating an image inside a holder (ch-item) as shown below:
<div class="ch-item ch-img-1" style="background: url(<?php echo get_template_directory_uri(); ?>/images/image1.jpg);">
If possible we would like to make this image change to another when clicked, and repeat this process six times in all, so each time it is clicked it changes to another image.
We would greatly appreciate any help. Thank you!

This is one way to do it using solely Javascript:
// Counter to keep track of which the current image is
var counter = 0;
// List of images
var images = [
'http://cdn.cutestpaw.com/wp-content/uploads/2011/11/Seemly-l.jpg',
'http://cdn.cutestpaw.com/wp-content/uploads/2011/11/Handsome-l.jpg',
// Add more images here
];
window.onload = function () {
// Get the container div
var gallery = document.getElementById('gallery');
// Run updateImage function on click
gallery.addEventListener('click', updateImage);
// Run updateImage on start
updateImage();
}
function updateImage() {
// Get the container div
var gallery = document.getElementById('gallery');
// Set background image
gallery.style.backgroundImage = 'url(' + images[counter] + ')';
// Update counter
counter++;
// Remove old class name
if (counter == 1) { // Remove last
gallery.className = gallery.className.replace(
' ch-img-' + images.length,
''
);
} else { // Remove previous
gallery.className = gallery.className.replace(
' ch-img-' + (counter - 1),
''
);
}
// Add new class name
gallery.className = gallery.className + ' ch-img-' + (counter);
// Reset counter when at the end of the images list
if (counter == images.length) {
counter = 0;
}
}
And here is a JSFiddle to try it out:
https://jsfiddle.net/0tg6up0o/14/

Related

Counting number of images in folder (sort of)

What I am trying to do is an image gallery in which you can navigate by arrows (left and right). There is x images in the image folder (for example let it be 8). Clicking the left arrow triggers the left() function:
function left() {
number--; // number variable is 1 for default, it's used for changing images which are named slide1 slide2... so I can change it like that: "slide" + number
document.getElementById("js_gallery_image").setAttribute("src", "img/" + "slide" + number + ".jpg"); //changes the number
and the right arrrow triggers the right() function which is the same but with number++ instead of number--.
And this was the code that I made at first but there is one more thing: when you go to the last image (8th one) clicking the right button should show the first image. I did it by adding an invisible img tag named #test, so I changed the right() function to that:
function right() {
number++;
document.getElementById("test").setAttribute("src", "img/" + "slide" + number + ".jpg"); //changes the test image path to next slide.
document.getElementById("test").onload = () => change(); // if number isn't greater than 8 image will load and change() function will change the image in gallery
document.getElementById("test").onerror = () => {
number = 1;
change();
}; // if number is greater than 8 it will throw an error so number will be changed to one and the change() function will be triggered.
};
and that worked, but how to do it with the left function, so when the first image is displayed and you click the left arrow it will show you the last image? I tried to do that:
function left() {
number--;
document.getElementById("test").setAttribute("src", "img/" + "slide" + number + ".jpg");
document.getElementById("test").onload = () => change();
document.getElementById("test").onerror = () => {
let err = false;
do {
number++
document.getElementById("test").setAttribute("src", "img/" + "slide" + number + ".jpg");
document.getElementById("test").onerror = () => err = true;
} while (err == false) //it pluses 1 to number untill test image throws an error which should be thrown when the number is greater than 8
};
And this didn't work, it gives me a result of an infinite loop. I trieed to do that using break statements and others but nothing worked.
From what it looks like, you have an issue with the loop and the fact that it is adding a listener, but is not waiting for the listener to do anything, causing the code to just loop and not wait for anything, and changing it again, not wait...
the fix for that could be to just make another loop inside of a loop and set the number to a variable to reduce having to download the same assets multiple times.
The code would look like this:
let maxImg = 0;
function findMax(){
let currentMax = 1; //initially sets it to one because I presume you will have at least one image in the gallary
let stoploop = false;
let testImg = new Image();
testImg.onload = function () {
currentMax += 1;
stoploop = true;
}
testImg.onerror = function () {
maxImg = currentMax;
stoploop = true;
}
testImg.setAttribute("src", "img/" + "slide" + (currentMax + 1) + ".jpg");
function loop() {
setTimeout(function () {
if (!stoploop) {
loop();
} else {
if (maxImg < 1) {
testImg.setAttribute("src", "img/" + "slide" + (currentMax + 1) + ".jpg");
loop();
}
}
}, 500);//done to not completely bog down the computer, may adjust if needbe
}
loop();
}
so in practice, you would have to have your left function look like this:
function left() {
number--;
document.getElementById("test").setAttribute("src", "img/" + "slide" + number + ".jpg");
document.getElementById("test").onload = () => change();
document.getElementById("test").onerror = () => {
document.getElementById("test").setAttribute("src", "img/" + "slide" + maxImg + ".jpg");
number = maxImg;
};
}
NOTE: With your current solution of testing through the client side you will have to have increased load time because you have to load all of the images, and that includes waiting for the images to be downloaded from the server one by one.
Have a go with this
let number = 0;
let last = 9999999;
const img = document.getElementById("test")
const prev = document.getElementById("prev");
const next = document.getElementById("next");
const changeImg = () => img.setAttribute("src", "img/" + "slide" + number + ".jpg");
img.onerror = () => { // should only trigger once at the end of the list
last = number - 1;
if (number<0) {
console.log("no images found")
return;
}
number = last;
changeImg()
}
nav.addEventListener("click",function(e) {
tgt = e.target;
dir = tgt.id === "prev" ? -1 : 1;
number += dir
if (number < 0 || number >= last) number = 0;
prev.disabled=number===0;
changeImg()
})
<div id="nav">
<button class="btn" id="prev" disabled type="button">Prev</button>
<img id="test" src="img/slide0.jpg">
<button class="btn" id="next" type="button">Next</button>
</div>
See if this helps:
Working example: https://jsfiddle.net/diogocosta/5w042uL1/4/
HTML
<button id="prev-button" disabled onclick="prevImage()">Previous</button>
<button id="next-button" onclick="nextImage()">Next</button>
<img src="https://placeimg.com/300/300/any" id="img-content">
JS
const images = [
'https://placeimg.com/300/300/animals',
'https://placeimg.com/300/300/nature',
'https://placeimg.com/300/300/people',
'https://placeimg.com/300/300/tech',
'https://placeimg.com/300/300/sepia',
]
const TOTAL_IMGS = 5
let currentImg = 1
const imgContent = document.getElementById('img-content')
function nextImage () {
if (currentImg < TOTAL_IMGS) {
currentImg++
imgContent.setAttribute('src', images[currentImg-1])
}
updateButtonState()
}
function prevImage () {
if (currentImg > 1) {
currentImg--
imgContent.setAttribute('src', images[currentImg-1])
}
updateButtonState()
}
// Enables and disables button
function updateButtonState() {
const nextButton = document.getElementById('next-button')
const prevButton = document.getElementById('prev-button')
if (currentImg === 1) {
nextButton.removeAttribute('disabled')
prevButton.setAttribute('disabled', true)
} else if (currentImg === TOTAL_IMGS) {
nextButton.setAttribute('disabled', true)
prevButton.removeAttribute('disabled')
} else {
nextButton.removeAttribute('disabled')
prevButton.removeAttribute('disabled')
}
}
Cheers,

How do I change the image src in my slider?

I have this image for a slider. I want it to fade to the next image after the button is clicked. The JQuery makes the image fade in and out to make the transition cleaner when the src changes. However, the image stays the same after fading.
Html
<button onclick = "prev()" id = "prev">Prev</button>
<img id = "slider" src = "" height = "600px" width = "600px"/>
<button onclick = "next()" id = "next">Next</button>
JQuery
var images = ['', '', ''];
var num = 0;
function next() {
var slider = $('#slider');
num++;
if(num >= images.length) {
num = 0;
}
slider.fadeOut('slow', function() {
slider.src = images[num];
slider.fadeIn('slow');
});
}
function prev() {
var slider = $('#slider');
num--;
if(num < 0) {
num = images.length-1;
}
slider.fadeOut('slow', function() {
slider.src = images[num];
slider.fadeIn('slow');
});
}
I have taken out the images I tested it with as their links were too long. The three slider images would be in the JQuery "images" variable and the starting one in the image src.
Assuming that images is an array of image URLs, then your mistake is trying to set slider.src instead of slider.attr('src, value);.
So, use this instead:
slider.attr('src', images[num]);

limit javascript toggle according to select box value

Here is link of my current fiddle
jsFiddle
JS --
$('.click').on({
'click': function () {
var origsrc = $(this).attr('src');
var src = '';
if (origsrc == 'http://imageshack.us/a/img703/8236/l6hu.png') src = 'http://imageshack.us/a/img20/1651/fibz.png';
if (origsrc == 'http://imageshack.us/a/img20/1651/fibz.png') src = 'http://imageshack.us/a/img703/8236/l6hu.png';
$(this).attr('src', src);
}
});
i am able to toggle image onclick with another image and vice versa. This is okay, but i want to limit the toggle only when green image is already selected. If i select 3 from select box then i can toggle white image into green image only 3 times, not more than 3. I also need help for another scenerio - if i select 3 from select box and toggle first 3 image and next moment i change the 2nd image into white and click 5th image to turn green then it will be possible. I am week in javascript or jquery, so need proper information about this problem. So plz help me out.
Here is a more comprehensive approach fiddle which will keep your limit in sync and handle discrepancies when the limit changes.
var quantity = 0; // will maintain limit
var stack = []; // will maintain ordered green buttons
$("#select").change(runWrapper);
function runWrapper() {
quantity = Number($("#select").val()); // set the limit
groom(); // turn off those that were turned on last
//run(); // this is your run function, uncomment
}
function groom(){
// let's test if we are over the limit
while(stack.length > quantity) {
// remove last which was set to green
$(stack.pop()).trigger("click")
// to remove the oldest/first set to green use
// $(stack.shift()).trigger("click")
}
}
$('.click').on({
'click': function () {
var origsrc = $(this).attr('src');
var src = '';
if (origsrc == 'http://imageshack.us/a/img703/8236/l6hu.png') {
// limit reached
if(stack.length >= quantity) {
alert(quantity + " limit reached!");
return;
}
src = 'http://imageshack.us/a/img20/1651/fibz.png';
// turning green push the DOM reference to the top of the stack
stack.push(this);
}
if (origsrc == 'http://imageshack.us/a/img20/1651/fibz.png') {
src = 'http://imageshack.us/a/img703/8236/l6hu.png';
// turning white remove the DOM reference from stack
var self = this;
stack = $.grep(stack, function(val) {
return self != val;
})
console.warn(stack);
}
$(this).attr('src', src);
}
});
You can update the function like this - fiddle is here - http://jsfiddle.net/4QkM8/5/
I changed id of select box to selQty
var selectedCount = 0;
$('.click').on({
'click': function () {
var origsrc = $(this).attr('src');
var src = '';
if (origsrc == 'http://imageshack.us/a/img703/8236/l6hu.png'){ if (selectedCount < $('#selQty').val()){src = 'http://imageshack.us/a/img20/1651/fibz.png';
selectedCount ++;
} }
if (origsrc == 'http://imageshack.us/a/img20/1651/fibz.png') {src = 'http://imageshack.us/a/img703/8236/l6hu.png';selectedCount --;}
$(this).attr('src', src == '' ? origsrc : src);
}
});
use a variable to keep track of how many items have been selected, and compare it to the quantity in the select box.
var count = 0;
var unselected_img = 'http://imageshack.us/a/img703/8236/l6hu.png';
var selected_img = 'http://imageshack.us/a/img20/1651/fibz.png';
$('.click').on({
'click': function () {
var max_allowed = parseInt($("#select").val(), 10);
var origsrc = $(this).attr('src');
var src = '';
if (origsrc == unselected_img && count < max_allowed) {
src = selected_img;
count++;
} else if (origsrc == selected_img) {
src = unselected_img;
count--;
} else {
alert("Too many selected.");
}
if (src) {
$(this).attr('src', src);
}
}
});
DEMO

Fading Image Slider

I'm trying to fade images in and out of each other. I'm not sure if it's better to preload the image before hand or not. Pretty much what's happening is that fade is hitting completely white background before fading in the next image, but I want it to fade immediatly instead of showing the white background - if that makes sense:
$(document).ready(function () {
var $next,
cycle;
var i = 0;
var imgArr = ['1.jpg', '2.jpg', '3.jpg'];
$activeLi = $("#slideshow li");
$activeLi.html('<img src="images/' + imgArr[i] + '" />');
cycle = setInterval(change_img, 1000);
function change_img(){
clearInterval(cycle);
$activeLi.find('img').fadeOut('slow', function(){
$activeLi.html('<img src="images/' + imgArr[i] + '" />').fadeIn('slow');
});
i = (i == (imgArr.length - 1)) ? 0 : ++i;
cycle = setInterval(change_img, 1000);
}
});
Also is it better to prealod my images before fading them in?
JSFiddle
My Solution (Which is jaded sinced I started the question...)
$(document).ready(function () {
var $next,
cycle;
var i = 0;
var durTimer = 2000;
var imgArr = ['1.jpg', '2.jpg', '3.jpg', '4.jpg'];
$activeLi = $("#slideshow li");
$activeLi.first().html('<img src="images/' + imgArr[0] + '" />');
cycle = setInterval(change_img, durTimer);
function change_img(){
clearInterval(cycle);
var nxtImg = (i == imgArr.length) ? 1 : i;
$activeLi.last().html('<img src="images/' + imgArr[nxtImg] + '" />');
$activeLi.find('img').animate({opacity:0}, {duration: durTimer});
i = (i == (imgArr.length - 1)) ? 0 : ++i;
$activeLi.first().html('<img src="images/' + imgArr[i] + '" />');
cycle = setInterval(change_img, durTimer);
}
});
If you have limited number of images, it is better to load all of them on page load.
In the given example, you are using only one img tag and changing the source of that to another image after some time.
So, when the image is faded out, definitely we can see the white background. Also it will take some time to load the new image.
Instead of a single img tag, add three img tags (from your code, there are three images).
Start both the fadeOut and fadeIn animations at a time.
fadeOut for current image and fadeIn for next image.
This will not show any white background.
I already created a small demo for this.
Check this out : http://db.tt/q8VPb03U

jQuery swap Next/Previous image, images in array

I have a literal array of image IDs and I need to swap them in <img src=""> to Next or Previous image on buttons click events. The initial current image ID is known from the img src provided server-side on initial page load.
Obviously, before swapping, the URL needs to be constructed with the target ID like this:
'http://site.com/images/' + imageID + '.jpg'
I'm a JS/jQuery beginner and would like to learn a correct, minimalistic approach. TIA.
My code to start off:
var images=["777777","666666","555555"];
var max = $(images).length;
$('#swapnextimg').click{
$("#imageswap").attr('src', ...... );
}
<a id="swapnextimg"></a>
<a id="swapprevsimg"></a>
<div id="imagebox">
<img id="imageswap" src="http://site.com/images/123456.jpg">
</div>
Here is an example:
http://jsfiddle.net/ndFGL/
$(function() {
// Image ID array
var images = ['240', '260', '250', '123', '200'];
var max = images.length;
// Get current image src
var curSrc = $('#imageswap').attr('src');
// Find ID in image src
var curID = curSrc.replace(/.*\/(.*?)\.jpg/i, '$1');
var curIdx = 0;
// Search image list for index of current ID
while (curIdx < max) {
if (images[curIdx] == curID) {
break;
}
curIdx++;
}
// For convenience
var imgSrcBase = 'http://placehold.it/';
// Next image on button (and image) click
$('#swapnextimg,#imageswap').click( function() {
curIdx = (curIdx+1) % max;
$("#imageswap").attr('src', imgSrcBase+images[curIdx]+'.jpg');
});
// Prev image on button click
$('#swapprevsimg').click( function() {
curIdx = (curIdx+max-1) % max;
$("#imageswap").attr('src', imgSrcBase+images[curIdx]+'.jpg');
});
});
Try below code,
var images=["777777","666666","555555"];
var max = $(images).length;
var imgPtr = 0;
$('#swapnextimg').click{
if (imgPtr == max) {
//comment the below return and set imgPtr to 0 for rotating the images
return;
}
$("#imageswap").attr('src', 'http://site.com/images/' + images[imgPtr++] + '.jpg');
}
$('#swapprevsimg').click{
if (imgPtr == 0) {
//comment the below return and set imgPtr to max-1 for rotating the images
return;
}
$("#imageswap").attr('src', 'http://site.com/images/' + images[imgPtr--] + '.jpg');
}
<a id="swapnextimg"></a>
<a id="swapprevsimg"></a>
<div id="imagebox">
<img id="imageswap" src="http://site.com/images/123456.jpg">
</div>
I assume that you've got one img tag, and only one. And that the purpose of this is to change that single image tag.
To do that you will need the nex and prev button.
<div id="container">
<img src="#" data-num="" />
<span class"prev">prev</span>
<span class"next">next</span>
</div>
The object:
var obj = [0: 'dog', 1: 'cat'];
now for the next and prev to work. We are going to take a look at the .on() method.
$('.container span').on('click', function(){
var $this = $(this), // span
currentNum = $this.siblings('img').data('num'), // img data-num
nextNum = $this.is('.next') ? currentNum+1 : currentNum-1, // if class is next add 1, if not remove 1
link = "http://site.com/images/" + obj[nextNum] + ".jpg" // the link
// either it's not the last images or it returns
nextNum != obj.length() || return
$('img').attr('src', link).data('num', nextNum)
})
Hope this helped you. If not please let me know

Categories