Next/prev button for modal with Javascript - javascript

I have been trying to make modal for a custom site I'm building. Everything seemed to go fine. It displayed whichever picture I clicked on and "previous" button works as intended. However, there seems to be a problem with "next" button because it behaves differently depending on which picture I'm currently on. Sometimes it jumps by few indexes forward or even backwards. Some insight would be appreciated. Thanks in advance. Here is a code HTML:
<div id="modalcontainer" class="displaynone">
<h4>
<span id="close">X</span>
</h4>
<img src="" alt="" id="modalcontent">
<div class="buttoncontainer">
<div class="previous">
<span id="prev"><</span>
</div>
<div class="next">
<span id="next">></span>
</div>
</div>
</div>
<div id="imgcontainer">
<img src="images/1.JPG" alt="">
<img src="images/2.JPG" alt="">
<img src="images/3.JPG" alt="">
<img src="images/4.JPG" alt="">
<img src="images/8.png" alt="">
<img src="images/9.jpg" alt="">
<img src="images/10.jpg" alt="">
</div>
And JS:
const modalContainer = document.getElementById("modalcontainer");
const prevButton = document.getElementById("prev");
const nextButton = document.getElementById("next");
const closeModal = document.getElementById("close");
const modalContent = document.getElementById("modalcontent");
const imgContainer = document.getElementById("imgcontainer");
let containerImages = imgContainer.querySelectorAll("img");
let imgIndex = 0;
containerImages.forEach(function(img){
img.setAttribute("data-index", imgIndex++);
img.addEventListener("click", () => {
if(modalContainer.classList.contains("displaynone")){
modalContainer.classList.remove("displaynone");
modalContainer.classList.add("displaymodal");
modalContent.src = img.src;
};
imgIndex = img.dataset.index;
console.log(imgIndex);
});
});
closeModal.addEventListener("click", () => {
if(modalContainer.classList.contains("displaymodal")){
modalContainer.classList.remove("displaymodal");
modalContainer.classList.add("displaynone");
}
imgIndex = 0;
});
nextButton.addEventListener("click", () => {
imgIndex = (imgIndex += 1) % containerImages.length;
modalContent.src = containerImages[imgIndex].src;
console.log(imgIndex);
});
prevButton.addEventListener("click", () => {
imgIndex = (imgIndex -= 1);
if (imgIndex < 0) {
imgIndex = containerImages.length - 1;
console.log(imgIndex);
};
modalContent.src = containerImages[imgIndex].src;
console.log(imgIndex);
});

I dummied up some objects to get it to run and your previous/next button code seems to work. It there some other code that might be involved? Something modifying the number of images in the imageContainer?
const prevButton = document.querySelector("#prev");
const nextButton = document.querySelector("#next");
let images = document.querySelectorAll("img");
let imgIndex = 0;
images.forEach((img) =>
img.addEventListener("click", () => {
imgIndex = parseInt(img.dataset.index);
setSelected();
})
);
setSelected();
prevButton.addEventListener("click", () => {
imgIndex = imgIndex -= 1;
if (imgIndex < 0) imgIndex = images.length - 1;
setSelected();
});
nextButton.addEventListener("click", () => {
imgIndex = (imgIndex += 1) % images.length;
setSelected();
});
function setSelected() {
images.forEach((img) => img.classList.remove("selected"));
images[imgIndex].classList.add("selected");
}
img {
display: inline-block;
border: 2px solid transparent;
}
.selected {
border: 2px solid red;
}
<div id="imageContainer">
<img src="https://picsum.photos/100?random=1" data-index="0">
<img src="https://picsum.photos/100?random=2" data-index="1">
<img src="https://picsum.photos/100?random=3" data-index="2">
<img src="https://picsum.photos/100?random=4" data-index="3">
</div>
<div>
<button id="prev">Prev</button>
<button id="next">Next</button>
</div>

Related

whenever an image starts to get deleted onclick it wont stop

I made this button, and added Math.floor(Math.random() * 2 + 1) to it to give wrong and correct randomly. and i added 5 images as lifes that whenever I get wrong one of the images will get hidden or removed. but I'm getting 2 problems:
the first one is that whenever an image gets deleted it wont stop and it deletes all the other images without returning to the math.random.
second problem is that when i get wrong answer it takes to clicks to start deleting the images.
I've been trying to fix it but I just couldn't figure it out!
you can run the code yourself and try it if you didnt understand what i ment!
if you do help, pleas explain to me what was the problem!!
var button1 = 1;
var span1 = document.getElementById("count1");
var span2 = document.getElementById("count2");
document.getElementById("button1").onclick = function() {
let btn1 = Math.floor(Math.random() * 2 + 1);
if (btn1 == 1) {
if (parseInt(span1.innerHTML) < 10)
span1.innerHTML = parseInt(span1.innerHTML) + 1;
} else if (parseInt(span2.innerHTML) < 5) {
let imageToDelete = 1;
document.getElementById("button1").onclick = function() {
document.getElementById("image_" + imageToDelete).style.visibility = "hidden";
imageToDelete++;
span2.innerHTML = parseInt(span2.innerHTML) + 1;
}
}
}
<input id="button1" type="button" value="click me?" style="height: 100px; width: 100px;">
<div style="margin-top: 40px;"></div>
<div id="output">
<img id="image_1" src="/images/person1.jpg">
<img id="image_2" src="/images/person1.jpg">
<img id="image_3" src="/images/person1.jpg">
<img id="image_4" src="/images/person1.jpg">
<img id="image_5" src="/images/person1.jpg">
</div>
<p id="p1">CORRECT: <span id="count1">0</span></p>
<p id="p2">ERROR: <span id="count2">0</span></p>
Something like this maybe?
//var button1 = 1;
var span1 = document.getElementById("count1");
var span2 = document.getElementById("count2");
var lives = document.getElementsByClassName("img");
var deads = 0;
document.getElementById("button1").onclick = function() {
if (deads >= 5) {
alert('no more lives');
return;
}
var rand = Math.random();
var sp1 = parseInt(span1.innerHTML);
var sp2 = parseInt(span2.innerHTML);
if (rand < .5 && sp1 < 10) {
if (deads > 0) deads--;
sp1++;
span1.innerHTML = sp1;
lives[deads].style.visibility = 'visible';
} else {
sp2++;
span2.innerHTML = sp2;
lives[deads].style.visibility = 'hidden';
deads++;
}
}
<input id="button1" type="button" value="click me?" style="height: 100px; width: 100px;">
<div style="margin-top: 40px;"></div>
<div id="output">
<img id="image_1" class='img' src="/images/person1.jpg">
<img id="image_2" class='img' src="/images/person1.jpg">
<img id="image_3" class='img' src="/images/person1.jpg">
<img id="image_4" class='img' src="/images/person1.jpg">
<img id="image_5" class='img' src="/images/person1.jpg">
</div>
<p id="p1">CORRECT: <span id="count1">0</span></p>
<p id="p2">ERROR: <span id="count2">0</span></p>

simple picture over picture in html

im trying to build a website, where u click on a text, and a picture appears, when you click on this picture, the next one appears and so on. If you reach the last picture, the first one should appear if you click on it. My code is very complicated and it does not work with the last picture. I hope somebody can help me!
<head>
<script type="text/javascript">
function showImage() {
document.getElementById('loadingimage').style.visibility="visible";
}
function showImage2() {
document.getElementById('loadingimage2').style.visibility="visible";
}
function showImage3() {
document.getElementById('loadingimage3').style.visibility="visible";
}
</script>
</head>
<body>
<a onclick="showImage()">Hier clicken</a>
<img onclick="showImage2()" id="loadingimage" src="pic/pic1.jpg" alt="" style="visibility:hidden"></img>
<img onclick="showImage3()" id="loadingimage2" src="pic/pic2.jpg" alt="" style="visibility:hidden"></img>
<img onclick="showImage4()" id="loadingimage3" src="pic/pic3.jpg" alt="" style="visibility:hidden"></img>
</body>
For simplicity, the button will be hidden after you click the first time on the button.
let start = 0,
total = 3,
hasStarted = false;
const images = [...document.querySelectorAll(".image")];
const button = document.querySelector("button");
function showImage() {
if (!hasStarted) {
button.classList.add("hide")
hasStarted = !hasStarted;
}
images.forEach(image => {
if (image.classList.contains("show")) {
image.classList.remove("show");
image.classList.add("hide");
}
})
document.querySelector(`.image${start}`).classList.add("show");
++start;
start = start % total;
}
images.forEach(image => {
image.addEventListener("click", showImage)
})
.hide {
visibility: hidden;
}
.show {
visibility: visible;
}
<button onclick="showImage()">Hier clicken</button>
<img class="image image0 hide" id="loadingimage1" src="https://source.unsplash.com/random/200x200" alt=""></img>
<img class="image image1 hide" id="loadingimage2" src="https://source.unsplash.com/random/200x200" alt=""></img>
<img class="image image2 hide" id="loadingimage3" src="https://source.unsplash.com/random/200x200" alt=""></img>
I feel this is what you need:
<head>
<script type="text/javascript">
function showImage() {
document.getElementById('loadingimage').style.visibility = "visible";
document.getElementById('loadingimage').style.position = 'absolute';
}
function showImage2() {
document.getElementById('loadingimage2').style.visibility = "visible";
document.getElementById('loadingimage2').style.zIndex = '10';
document.getElementById('loadingimage2').style.position = 'absolute'
}
function showImage3() {
document.getElementById('loadingimage3').style.visibility = "visible";
document.getElementById('loadingimage3').style.zIndex = '15';
document.getElementById('loadingimage3').style.position = 'absolute'
}
function showImage4() {
document.getElementById('loadingimage').style.zIndex = '20';
}
</script>
</head>
<body>
<a onclick="showImage()">Hier clicken</a>
<img onclick="showImage2()" id="loadingimage" src="https://source.unsplash.com/random/200x201" alt="" style="visibility:hidden">
<img onclick="showImage3()" id="loadingimage2" src="https://source.unsplash.com/random/200x202" alt="" style="visibility:hidden">
<img onclick="showImage4()" id="loadingimage3" src="https://source.unsplash.com/random/200x203" alt="" style="visibility:hidden">
</body>

change position of images in an array

I am adding an image slider to my page and are trying to change the image when I click either the "left button" or "right button"
<div class="gallary">
<img class="img" src='https://images.unsplash.com/photo-1587374194137-681fd73fab43?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='0'>
<img class="img" src='https://images.unsplash.com/photo-1586283294663-b82b25f4d660?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='1'>
<img class="img" src='https://images.unsplash.com/photo-1502945015378-0e284ca1a5be?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='2'>
<img class="img" src='https://images.unsplash.com/photo-1552236867-1caaa93299e2?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='3'>
</div>
<button class="button left" >
Scroll left
</button>
<button class="button right" >
scroll right
</button>
And for my js file I have selected the left and right button and added a event listener to the left button
const btnLeft = document.querySelector(".left");
const btnRight = document.querySelector(".right");
let images = document.querySelectorAll("img");
let arr = [...images];
btnLeft.addEventListener("click", function(){
arr.push(arr.shift());
console.log(arr);
})
When I console log the array inside the function it changes order as I want to but nothing happens to my images. They stay in the same position.
Any suggestions to what I should do?
You have created a copy of images. Changing image array position, wont reflect in DOM. You need to clear dom and reconstruct it.
Suggestion: Instead of creating dom, use show hide on element based on position
const btnLeft = document.querySelector(".left");
const btnRight = document.querySelector(".right");
let images = document.querySelectorAll("img");
let arr = [...images];
const gallary = document.querySelector(".gallary");
btnLeft.addEventListener("click", function () {
gallary.innerHTML = "";
arr.push(arr.shift());
arr.forEach((dom) => {
gallary.append(dom);
});
});
<div class="gallary">
<img class="img" src='https://images.unsplash.com/photo-1587374194137-681fd73fab43?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='0'>
<img class="img" src='https://images.unsplash.com/photo-1586283294663-b82b25f4d660?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='1'>
<img class="img" src='https://images.unsplash.com/photo-1502945015378-0e284ca1a5be?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='2'>
<img class="img" src='https://images.unsplash.com/photo-1552236867-1caaa93299e2?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='3'>
</div>
<button class="button left" >
Scroll left
</button>
<button class="button right" >
scroll right
</button>
Better solution:
const btnLeft = document.querySelector(".left");
const btnRight = document.querySelector(".right");
let images = document.querySelectorAll("img");
let activeIndex = 0;
toggleImage(activeIndex);
btnLeft.addEventListener("click", function () {
activeIndex -= 1;
if (activeIndex < 0) {
activeIndex = images.length-1;
}
toggleImage(activeIndex);
});
btnRight.addEventListener("click", function () {
activeIndex += 1;
if (activeIndex >= images.length) {
activeIndex = 0;
}
toggleImage(activeIndex);
});
function toggleImage(index) {
images.forEach((img) => {
img.classList.remove("active");
img.classList.add("hide");
});
images[index].classList.remove("hide");
images[index].classList.add("active");
}
.active {
border: 1px solid;
display: block;
}
.gallary .hide {
display: none;
}
<div class="gallary">
<img class="img" src='https://images.unsplash.com/photo-1587374194137-681fd73fab43?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='0'>
<img class="img" src='https://images.unsplash.com/photo-1586283294663-b82b25f4d660?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='1'>
<img class="img" src='https://images.unsplash.com/photo-1502945015378-0e284ca1a5be?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='2'>
<img class="img" src='https://images.unsplash.com/photo-1552236867-1caaa93299e2?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' alt='3'>
</div>
<button class="button left" >
Scroll left
</button>
<button class="button right" >
scroll right
</button>

How do I make a function that reset the game on click

I am working on a rock paper scissor game. I'm very new to javascript and only know the basics. The code is a little sloppy. What I want is to be able to continue playing the game after a choice is selected. For example, right now if I click rock, the CPU will randomize a result, but then if I click on paper, the result will stay on the screen and the new result will overlap the old one.
I was thinking of adding another condition to the if statements. Also, I was thinking of adding another function to the return of the if statement that might reset it.
html
<div class="main-container">
<div class="score">
<p>You:0</p>
<p>Computer:0</p>
</div>
<div class="user-choice">
<img id="rock" class="choice" src="icons/rock.png">
<img id="paper" class="choice" src="icons/paper.png">
<img id="scissors" class="choice" src="icons/scissors.png">
</div>
<div class="cpu-result">
<img class="cpu-rock" src="icons/rock.png">
<img class="cpu-paper" src="icons/paper.png">
<img class="cpu-scissors" src="icons/scissors.png">
</div>
</div>
js
const userChoice = document.querySelectorAll('.choice')
const cpuScissors = document.querySelector('.cpu-scissors')
const cpuPaper = document.querySelector('.cpu-paper')
const cpuRock = document.querySelector('.cpu-rock')
function cpuChoice() {
const rand = Math.random()
if (rand < .34) {
cpuPaper.style.display = 'inline-block'
} else if (rand >= .67) {
cpuRock.style.display = 'inline-block'
} else {
cpuScissors.style.display = 'inline-block'
}
}
userChoice.forEach(userChoice =>
userChoice.addEventListener('click', cpuChoice))
css
.cpu-scissors {
display: none;
}
.cpu-paper {
display: none;
}
.cpu-rock {
display: none;
}
.cpu-result img {
position: absolute;
height: 11rem;
}
Firstly, you need to remove position: absolute; for img which was causing the overlapping.
Secondly, each time you call cpuChoice(), you need to hide the previous element before showing the current element.
const userChoice = document.querySelectorAll('.choice')
const cpuScissors = document.querySelector('.cpu-scissors')
const cpuPaper = document.querySelector('.cpu-paper')
const cpuRock = document.querySelector('.cpu-rock')
let currentItem;
function cpuChoice() {
const rand = Math.random();
if (currentItem) {
currentItem.style.display = 'none';
}
if (rand < .34) {
cpuPaper.style.display = 'inline-block';
currentItem = cpuPaper;
} else if (rand >= .67) {
cpuRock.style.display = 'inline-block';
currentItem = cpuRock;
} else {
cpuScissors.style.display = 'inline-block';
currentItem = cpuScissors;
}
}
userChoice.forEach(userChoice =>
userChoice.addEventListener('click', cpuChoice));
.cpu-scissors {
display: none;
}
.cpu-paper {
display: none;
}
.cpu-rock {
display: none;
}
.cpu-result img {
height: 5rem;
}
<div class="main-container">
<div class="score">
<p>You:0</p>
<p>Computer:0</p>
</div>
<div class="user-choice">
<img id="rock" class="choice" src="icons/rock.png">
<img id="paper" class="choice" src="icons/paper.png">
<img id="scissors" class="choice" src="icons/scissors.png">
</div>
<div class="cpu-result">
<img class="cpu-rock" src="icons/rock.png">
<img class="cpu-paper" src="icons/paper.png">
<img class="cpu-scissors" src="icons/scissors.png">
</div>
</div>
You don't need all those IDs and Classes.
Use Indexes!
Using indexes you can also retrieve the winner
See this answer: https://stackoverflow.com/a/53983473/383904
const moves = ["Rock", "Paper", "Scissors"],
messages = ["You won!", "AI won", "It's a draw!"], // [PL, AI, draw]
score = [0, 0, 0], // [PL, AI, draw]
ELS = sel => document.querySelectorAll(sel),
EL_result = ELS("#result")[0],
EL_PLScore = ELS("#PLScore")[0],
EL_AIScore = ELS("#AIScore")[0],
ELS_ai = ELS(".ai");
function game() {
const PL = +this.dataset.user; // Get played index as integer
const AI = ~~(Math.random() * 3); // All you need: 0, 1, 2
const result = PL === AI ? 2 : (AI + 1) % 3 === PL ? 0 : 1; // 0=PLwins 1=AIwins 2=draw
score[result]++; // Increment PL or AI's score (Increments number of draws too ;) )
EL_result.innerHTML = `You: ${moves[PL]}, AI: ${moves[AI]}, ${messages[result]}`;
EL_PLScore.textContent = score[0];
EL_AIScore.textContent = score[1];
ELS_ai.forEach(el => el.classList.remove('inline-block')); // Hide all
ELS_ai[AI].classList.add('inline-block'); // Show one
}
// EVENTS:
document.querySelectorAll("[data-user]").forEach(el => el.addEventListener("click", game));
.ai {
display: none;
}
.ai.inline-block {
display: inline-block
}
<div class="main-container">
<div class="score">
<span>You: <span id="PLScore">0</span></span>
<span>Computer: <span id="AIScore">0</span></span>
</div>
<div class="user-choice">
<img data-user="0" src="//placehold.it/50x50/888?text=ROCK">
<img data-user="1" src="//placehold.it/50x50/eee?text=PAPER">
<img data-user="2" src="//placehold.it/50x50/0bf?text=SCISSORS">
</div>
<div class="cpu-result">
<img class="ai" src="//placehold.it/50x50/888?text=ROCK">
<img class="ai" src="//placehold.it/50x50/eee?text=PAPER">
<img class="ai" src="//placehold.it/50x50/0bf?text=SCISSORS">
</div>
<div id="result"></div>
</div>

Javascript Picture Slideshow

I'm using the basic code shown on https://www.w3schools.com/w3css/w3css_slideshow.asp to create an automatic slideshow for a website. Everything seems to be the same and for some reason, the slideshow is not working.
HTML:
<article id="elements">
<h2 class="major">Pictures</h2>
<div class="slideshow">
<script src="assets/slideshow.js"></script>
<img id="slide" src="images/colin1.jpg" style="width:75%">
<img id="slide" src="images/luke.jpg" style="width:75%">
<img id="slide" src="images/shep.jpg" style="width:75%">
</div>
CSS:
body #elements .slideshow #slide {
display: none;
}
JS:
var index = 0;
slideshow();
function slideshow() {
var i, x;
x = document.getElementById("slide");
for (i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
index++;
if (index > x.length) {
index = 1;
}
x[index-1].style.display = "block";
setTimeout(slideshow, 2000);
}
I appreciate anyone's help, and any ideas!
Agree with Gordon.
When selecting by ID only one element will be selected.
If you switch to using classes. e.g.
<img class="slide" src="images/colin1.jpg" style="width:75%">
Then you can select all the images using.
x = document.querySelectorAll(".slide");
which will return a nodeList, a similar construction to an Array but with different methods; that can be accessed via index. x[0], x[1], x[2].
hope this helps.
getElementById only returns one item, not an array, so you cannot use it to get all slides, use getElementsByClassName (https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementsByClassName), and change id for classes:
var index = 0;
slideshow();
function slideshow() {
var i, x;
x = document.getElementsByClassName("slide");
for (i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
index++;
if (index > x.length) {
index = 1;
}
x[index - 1].style.display = "block";
setTimeout(slideshow, 2000);
console.log('changed image')
}
#elements .slideshow #slide {
display: none;
}
<article id="elements">
<h2 class="major">Pictures</h2>
<div class="slideshow">
<script src="assets/slideshow.js"></script>
<img class="slide" src="images/colin1.jpg" style="width:75%">
<img class="slide" src="images/luke.jpg" style="width:75%">
<img class="slide" src="images/shep.jpg" style="width:75%">
</div>
</article>

Categories

Resources