I've have this code here: https://codepen.io/double_milkshake/pen/VwZJjgq
const nextBtn = document.querySelector('.nextBtn');
const prevBtn = document.querySelector('.prevBtn');
const container = document.querySelector('.images');
const textElement = document.querySelector(".text");
let counter = 0;
nextBtn.addEventListener('click',nextSlide);
prevBtn.addEventListener('click',prevSlide);
function nextSlide() {
container.animate([{opacity: '0.1'},{opacity: '1.0'}],{duration:500, fill: 'forwards'});
if(counter === 4) {
counter = -1;
}
counter++;
container.style.backgroundImage = `url(img/bcg-${counter}.png)`
}
function prevSlide() {
container.animate([{opacity: '0.1'},{opacity: '1.0'}],{duration:1000, fill: 'forwards'});
if(counter === 0) {
counter = 5;
}
counter--;
container.style.backgroundImage = `url(img/bcg-${counter}.png)`
}
It is a simple image slider. You can't see the images, because the code is made for images that are on your local drive. Every time you click the button, the counter changes and this way the image changes.
Now I would like to change the text, when clicking as well. But not sure How to start this, maybe you guys have any ideas?
Also any suggestions, what to do when I don't know How many images are in my folder. Currently they are hard coded to 5.
Thanks a lot!
HTML Markup:
<div class="text" id="caption">
This is image 1
</div>
Javascript
const nextBtn = document.querySelector('.nextBtn');
const prevBtn = document.querySelector('.prevBtn');
const container = document.querySelector('.images');
const textElement = document.querySelector(".text");
let counter = 0;
nextBtn.addEventListener('click',nextSlide);
prevBtn.addEventListener('click',prevSlide);
function nextSlide() {
container.animate([{opacity: '0.1'},{opacity: '1.0'}],{duration:500, fill: 'forwards'});
if(counter==4)
counter=-1;
counter = setText(counter, "up");
container.style.backgroundImage = `url(img/bcg-${counter}.png)`
}
function prevSlide() {
container.animate([{opacity: '0.1'},{opacity: '1.0'}],{duration:1000, fill: 'forwards'});
if(counter==-0)
counter=5;
counter = setText(counter, "down");
container.style.backgroundImage = `url(img/bcg-${counter}.png)`
}
function setText(cntr, direction){
if(direction=="up") {
cntr++;
} else {
cntr--;
}
if(cntr==0){
document.getElementById("caption").innerHTML = "This is image 1";
} else if(cntr==1){
document.getElementById("caption").innerHTML = "This is image 2";
} else if(cntr==2){
document.getElementById("caption").innerHTML = "This is image 3";
} else if(cntr==3){
document.getElementById("caption").innerHTML = "This is image 4";
} else if(cntr==4){
document.getElementById("caption").innerHTML = "This is image 5";
}
return cntr;
}
Related
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,
I wrote some JS code that rendering DOM (It is my custom carousel). My carousel has 2 buttons and they have some functions. When I trigger these functions in repeatedly, the DOM has difficulty in rendering. So the FPS of the page dropping slowly -half fps per second but very fast at beginning: 2-3 fps per second-.
You can see at right top (writes ortalama 2.68 fps):
https://ibb.co/8YvyJwn
And my performace json file:
https://gofile.io/?c=LIHiLh
const hizmetler = [{/* some datas */}];
var index = 0;
var slaytCount = hizmetler.length;
showSlide(index);
function showSlide(i) {
index = i;
if (i < 0) {
index = slaytCount - 1;
}
if (i >= slaytCount) {
index = 0;
}
const baslik = document.querySelector(".carousel-baslik");
const metin = document.querySelector(".carousel-metin");
const image = document.querySelector(".carousel-lg-image");
const iconGround = document.querySelector(".icon-ground");
const counter = document.querySelector(".counter");
let iconImg = `<img src="${hizmetler[index].icon}" class="animated fadeInDown fast" alt="">`;
let lgImage = `<img src="${hizmetler[index].lgImage}" class="animated fadeIn fast" alt="">`;
baslik.innerHTML = hizmetler[index].baslik;
metin.innerHTML = hizmetler[index].metin;
image.innerHTML = lgImage;
counter.innerText = hizmetler[index].count;
iconGround.innerHTML = iconImg;
document.querySelector('.controller-left').addEventListener('click', function (e) {
index--;
showSlide(index);
iconImg = `<img src="${hizmetler[index].icon}" class="animated fadeInLeft faster" alt="">`;
document.querySelector(".icon-ground").innerHTML = iconImg;
});
document.querySelector('.controller-right').addEventListener('click', function (e) {
index++;
showSlide(index);
iconImg = `<img src="${hizmetler[index].icon}" class="animated fadeInRight faster" alt="">`;
document.querySelector(".icon-ground").innerHTML = iconImg;
});
}
I found to solution. When you run the click functions inside the showSlide function, something like an overload occurs and the page's FPS crashes. When I run the click functions independently, it does not cause any crash. \m/_
I don't understand why the previous image's being shown for a split second before moving on to the next image upon clicking.
Also, when I reach the last image, it should redirect to indexTwo.html which it does successfully. However, 'image down' coming from the alt attribute in <img/> is being shown for like two seconds before it reaches indexTwo.html successfully.
I tried many many different attempts to rectify this, way too many to list!
How can I prevent this behavior from happening?
Here's my html:
<img id="the-image" class="img-responsive"
src="http://tech21info.com/admin/wp-content/uploads/2013/03/chrome-logo-200x200.png"
alt="image down"
onclick="clickedImage()"
/>
Here's my js:
let theImage = document.getElementById('the-image');
let index = [
"http://tech21info.com/admin/wp-content/uploads/2013/03/chrome-logo-200x200.png",
"https://cdn.tutsplus.com/net/uploads/legacy/155_drupal/200x200.png",
"https://townandcountryremovals.com/wp-content/uploads/2013/10/firefox-logo-200x200.png"
];
let op = 1;
let imageId = 0;
let clickedImage = () => {
// start animation opacity
if(op === 1) {
let timer = setInterval(() => {
if(op <= 0.1) {
// load the next image
imageId = imageId + 1;
console.log(imageId);
theImage.src = index[imageId];
if (imageId >= index.length) {
window.location = "indexTwo.html";
}
// reset the opacity
theImage.style.opacity = op = 1;
clearInterval(timer);
} else {
op -= 0.1;
theImage.style.opacity = op;
}
}, 100);
}
};
The issue is that you are overflowing the array.
When imageId == 3 then the following line:
theImage.src = index[imageId];
results in theImage.src being set to undefined.
An easy way to resolve this would be to rearrange your code so that the image only advances to the next image if the id is within the bounds of the array.
let clickedImage = () => {
// start animation opacity
if(op === 1) {
let timer = setInterval(() => {
if(op <= 0.1) {
// load the next image
imageId = imageId + 1;
console.log(imageId);
if (imageId >= index.length) {
window.location = "indexTwo.html";
} else {
theImage.src = index[imageId];
// reset the opacity
theImage.style.opacity = op = 1;
}
clearInterval(timer);
} else {
op -= 0.1;
theImage.style.opacity = op;
}
}, 100);
}
};
var firstMove = 0;
var pictures = ['boar.jpg','lion.jpg','bones.jpg','eagle.jpg','wolf.jpg','boar.jpg','lion.jpg','bones.jpg','eagle.jpg','wolf.jpg','boar.jpg','lion.jpg','bones.jpg','eagle.jpg','wolf.jpg']
pictures.sort()
function replyClick(clicked_id)
{
//if player already draw one card;
if (firstMove){
var image = document.getElementById(clicked_id);
image.innerHTML = '<img src='+pictures[clicked_id-1]+' />'
var firstPicture = document.getElementById(firstMove);
if (image.innerHTML == firstPicture.innerHTML){
firstMove=0;
}
else {
image.innerHTML = "";
firstPicture.innerHTML = "";
firstMove=0
}
}
// if player didnt draw any card;
else {
var image = document.getElementById(clicked_id);
image.innerHTML = '<img src='+pictures[clicked_id-1]+' />'
firstMove = clicked_id
}
}
<div class="card" id="1" onclick="replyClick(this.id)"></div>
<div class="card" id="2" onclick="replyClick(this.id)"></div>
I try to create simple pexeso game.where you looking for two identical images.
My question is how to change this code to show that certain image right after somebody click on it.Because my script show image after inner condition but that is too late for me.Thanks for answer
Compare array elements.
pictures[clicked_id-1] == pictures[firstMove-1]
is the same that
image.innerHTML == firstPicture.innerHTML
UPD
For small delay use setTimeout
// other code
function replyClick(clicked_id) {
if (firstMove){
var imageSrc = pictures[clicked_id-1];
var prevImageSrc = pictures[firstMove-1];
var image = document.getElementById(clicked_id);
image.innerHTML = '<img src='+imageSrc+' />'
var firstPicture = document.getElementById(firstMove);
if (imageSrc == prevImageSrc) {
firstMove=0;
} else {
// code will run after 1s delay
setTimeout(function () {
image.innerHTML = "";
firstPicture.innerHTML = "";
firstMove=0;
}, 1000); // delay = 1 second
}
} else {
var image = document.getElementById(clicked_id);
image.innerHTML = '<img src='+pictures[clicked_id-1]+' />'
firstMove = clicked_id
}
}
i have added a light box function to my web page. everything works. so when i click on an image it goes bigger...
my problem is that there is no close button. how do i get it to close without having to click back.
Here is my code for the light box
window.onload = setupLightbox;
var lightboxOverlay;
var lightboxImage;
function setupLightbox() {
for (i in document.links) {
if(document.links[i].rel == "lightbox"){
document.links[i].onclick = showLightbox;
}
}
}
function showLightbox() {
lightboxOverlay = document.createElement("div");
lightboxImage = document.createElement("img");
lightboxOverlay.style.position = "fixed";
lightboxOverlay.style.top = lightboxOverlay.style.left ="0";
lightboxOverlay.style.width = lightboxOverlay.style.height ="100%";
lightboxOverlay.style.background = "#000";
lightboxOverlay.style.opacity = "0.5";
lightboxOverlay.style.filter = "alpha(opacity = 50)";
document.body.appendChild(lightboxOve…
lightboxImage.onload = showImage;
lightboxOverlay.onclick = closeLightbox;
lightboxImage.src = this.href;
return false;
}
function showImage(){
lightboxImage.style.position = "fixed";
lightboxImage.style.top = lightboxImage.style.left = "50%";
lightboxImage.style.marginLeft = -lightboxImage.width/2 + "px";
lightboxImage.style.marginTop = -lightboxImage.width/2 + "px";
lightboxImage.style.border = "10px solid #fff";
document.body.appendChild(lightboxIma…
}
function closeLightbox(){
lightboxImage.style.opacity = lightboxOverlay.style.opacity = "0";
setTimeout( function() {
lightboxImage.parentNode.removeChild…
lightboxOverlay.parentNode.removeChi…
}, 1);
}
Check the Lightbox should have a css file with it and an image folder too. Specify the css file in the header section so that it can find the image.