Some issues with an image carousel (JavaScript) - javascript

I'm making a image carousel to get some more experience.
I have an acf gallery in the back-end where i add my images.
This is the code that i use here:
<div class="images">
<img id="carousel_images_top" src="" alt="">
<div class="top_button next">Next</div>
<div class="top_button prev">Prev</div>
</div>
<script>
var imageList = [];
<?php
$images = get_field('image_carousel');
foreach($images as $img) {
echo "imageList.push('" . $img['url'] . "');";
}
?>
var imageTag = document.querySelector('#carousel_images_top');
imageTag.src = imageList[0];
function next() {
console.log(imageTag.src)
var curIndex = imageList.indexOf(imageTag.src);
imageTag.src = imageList[(curIndex+1) % imageList.length];
};
function prev() {
console.log(imageTag.src)
var curIndex = imageList.indexOf(imageTag.src);
imageTag.src = imageList[(curIndex-1 + imageList.length) % imageList.length];
};
document.querySelector('.next').addEventListener('click', next);
document.querySelector('.prev').addEventListener('click', prev);
</script>
I can see the first image in the array, and i can go back one to see the last one, but I can't go more than one back, and then forward to the first one again.
I do not get any errors at all, and I have tried to find out where the error is, but in the array, all of my 6 images is listed and the buttons are working.
I'm guessing there is an error in the curIndex variable, but I can't realy see what.
Anyone that can have a quick look and point me in the right direction?

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Static Template</title>
</head>
<body>
<div class="images">
<img id="carousel_images_top" src="" alt="">
<p>Current Index: <span id="currentindex"></span></p>
<div class="top_button next">Next</div>
<div class="top_button prev">Prev</div>
</div>
<script>
var imageList = [
'https://tse1-mm.cn.bing.net/th?id=OIP.2bdrFgmVuK6LO0ggJdNPZAHaFP&w=152&h=105&c=8&rs=1&qlt=90&dpr=1.5&pid=3.1&rm=2',
'https://tse1-mm.cn.bing.net/th?id=OIP.yP3sLQkAOswh1wDZq21NtwHaFj&w=144&h=105&c=8&rs=1&qlt=90&dpr=1.5&pid=3.1&rm=2',
'https://tse1-mm.cn.bing.net/th?id=OIP.FEUTSwbKW9ndBYzd-oI8OQHaIN&w=99&h=105&c=8&rs=1&qlt=90&dpr=1.5&pid=3.1&rm=2',
];
var imageTag = document.querySelector('#carousel_images_top');
var currentindexTag = document.getElementById('currentindex');
imageTag.src = imageList[0];
function next() {
//console.log(imageTag.src)
var curIndex = imageList.indexOf(imageTag.src);
imageTag.src = imageList[(curIndex+1) % imageList.length];
currentindexTag.innerHTML = curIndex;
};
function prev() {
//console.log(imageTag.src)
var curIndex = imageList.indexOf(imageTag.src);
imageTag.src = imageList[(curIndex-1 + imageList.length) % imageList.length];
currentindexTag.innerHTML = curIndex;
};
document.querySelector('.next').addEventListener('click', next);
document.querySelector('.prev').addEventListener('click', prev);
</script>
</body>
</html>
Follow the code you write, the images replacement does work correctly except the input of images array has same url.
Because the indexOf method returns the first index at which a given element can be found in the array, or -1 if it is not present.
var images = ['1.png', '1.png', '1.png'];
//no matter how many times to execute images.indexOf('1.png'), it's always return 0.
So, the better solution is that replacing of the curIndex with a global number, like below:
var curIndex = 0;
function prev() {
...
curIndex -= 1
}
function next() {
...
curIndex += 1;
}
This solution should be avoiding the problem you meet.
That's an example and it makes some evidences for the correct of your script.
There are two directions to find the problem is. One, to check the images input, and another, try to debug the code in reality environment.

Related

JS - I can get the value of input but not compare it

I'm learning JS and I'm trying to create a web game with javascript. The goal is simple: a flag is displayed at random, and the player must guess the name of the country associated with the flag.
The flag is randomly selected and displayed correctly, but I have a problem with the user interaction. I'd like to display "bad answer" in a <p> and if it's correct, display "good answer" (in a <p>), regenerate a flag and start again, indefinitely. The problem is that I can get the user's answer but i can't compare it to real answer and then display true or false.
I would like to know if someone could explain to me what is wrong and correct me please. Here is my code :
function getRandomInt(max) {
return Math.floor(Math.random() * max);
}
function getVal() {
const inputValue = document.querySelector('input').value;
console.log(inputValue);
}
function getData() {
var json = 'https://cdn.jsdelivr.net/npm/country-flag-emoji-json#2.0.0/dist/index.json'
fetch(json)
.then(data => data.json())
.then(data => {
const randomInt = getRandomInt(data.length);
console.log(data[randomInt]);
var image = document.getElementById("flag");
image.src = data[randomInt].image;
});
if (inputValue != data[randomInt].name.toLowerCase()) {
document.getElementsByClassName('result').class.add("result-false");
document.getElementsByClassName('result').innerHTML = 'Mauvaise Réponse';
} else if (inputValue == data[randomInt].name.toLowerCase()) {
document.getElementsByClassName('result').class.add("result-true");
document.getElementsByClassName('result').innerHTML = 'Bonne Réponse';
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Guess The Flag - </title>
<link rel="stylesheet" href="style.css">
<!-- <script type="text/js" src="app.js"></script> -->
</head>
<body>
<h1>GuessTheFlag</h1>
<div class="flagCanva">
<img id="flag" src="https://cdn.jsdelivr.net/npm/country-flag-emoji-json#2.0.0/dist/images/KH.svg" alt="">
</div>
<input type="text" name="flagName">
<button type="submit" onclick="getVal()">Je valide</button>
<p class="result"></p><br>
<button onclick="getData()">Next</button>
</body>
</html>
The reason is because the scope of inputValue is inside the function getVal only.
So in function getData it doesn't know inputValue.
The scope is the perimeter where the variable is known, it could be globally, local to a function, or at other level. It depends where and how you declare the variable.
It's an important thing to understand in most of the computer langage.
Here's a refactored working version with some comments to help clear things out:
function getRandomInt(max) {
return Math.floor(Math.random() * max);
}
let flag = "Cambodia"; // <= We need a global variable so that it can be set and accessed inside getVal() and getData()
function getVal() {
const inputValue = document.querySelector('input').value;
//>> Move the flag vs input comparison inside the input event handler:
if ( inputValue.toLowerCase() !== flag.toLowerCase()) { // <= Lowercasing both input and flag name to avoid case sensitive comparison failures
// Use `classList` instead of `class` to have access to the add() method
// Use `querySelector` to pick a single element instead of getElementsByClassName which returns a list of elements:
document.querySelector('.result').classList.add("result-false");
document.querySelector('.result').innerHTML = 'Mauvaise Réponse';
// No need for an else if here:
} else {
document.querySelector('.result').classList.add("result-true");
document.querySelector('.result').innerHTML = 'Bonne Réponse';
}
}
// TIP: Ideally the next function should be split into 2 functions:
// 1) fetchData(), runs once to grab the JSON
// 2) getRandomFlag(), runs on 'Next' click to get a random flag
// without re-fetching the JSON.
function getData() {
var json = 'https://cdn.jsdelivr.net/npm/country-flag-emoji-json#2.0.0/dist/index.json'
fetch(json)
.then(data=>data.json())
.then(data=> {
const randomInt = getRandomInt(data.length);
console.log(data[randomInt]);
var image = document.getElementById("flag");
image.src = data[randomInt].image;
flag = data[randomInt].name; // <= Set the value for the newly fetched flag name
});
}
Working demo:
function getRandomInt(max) {
return Math.floor(Math.random() * max);
}
let flag = "Cambodia"; // <= We need a global variable so that it can be set and accessed inside getVal() and getData()
function getVal() {
const inputValue = document.querySelector('input').value;
//>> Move the flag vs input comparison inside the input event handler:
if(inputValue.toLowerCase() != flag.toLowerCase()) {
// Use `classList` instead of `class` to have access to the add() method
// Use `querySelector` to pick a single element instead of getElementsByClassName which returns a list of elements:
document.querySelector('.result').classList.add("result-false");
document.querySelector('.result').innerHTML = 'Mauvaise Réponse';
} else {
document.querySelector('.result').classList.add("result-true");
document.querySelector('.result').innerHTML = 'Bonne Réponse';
}
}
function getData() {
var json = 'https://cdn.jsdelivr.net/npm/country-flag-emoji-json#2.0.0/dist/index.json'
fetch(json)
.then(data=>data.json())
.then(data=> {
const randomInt = getRandomInt(data.length);
console.log(data[randomInt]);
var image = document.getElementById("flag");
image.src = data[randomInt].image;
flag = data[randomInt].name;
});
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Guess The Flag - </title>
<link rel="stylesheet" href="style.css">
<!-- <script type="text/js" src="app.js"></script> -->
</head>
<body>
<h1>GuessTheFlag</h1>
<div class="flagCanva">
<img width="100" id="flag" src="https://cdn.jsdelivr.net/npm/country-flag-emoji-json#2.0.0/dist/images/KH.svg" alt="">
</div>
<input type="text" name="flagName">
<button type="submit" onclick="getVal()">Je valide</button>
<p class="result"></p><br>
<button onclick="getData()">Next</button>
</body>
</html>
There's a lot of refactoring that we can do (e.g. caching the selected elements, cache the json response to avoid re-fetching the data, removing global variables, etc.) to improve the code, but this is just a good start for a functional code.

Check for certain words in all paragraphs and add to list

I'm trying to check paragraphs to see if it contains a certain word (Apple), and if so, add that to a list.
<p>Orange</p>
<p>Grape</p>
<p>Apple</p>
<ul id=ulist>
</ul>
<script>
var i;
var x = document.getElementsByTagName("P");
for (i = 0; i < x.length; i++) {
document.getElementById("ulist").innerHTML = "<li>" + x[i].innerHTML + "<li>";
}
</script>
I'm unsure how to check for words, but first I'm trying to go through each paragraph and add each word to the list, but it's only adding Apple. I don't understand why even though I set i=0.
Expected output:
- Apple
New to Javascript so I'd appreciate if the solution uses simple code even if it's long.
Try this code:
var paragraphs = [...document.getElementsByTagName("P")];
var list = document.getElementById("ulist")
paragraphs.forEach(el => {
if (el.innerText.toLowerCase().includes("apple")) {
var li = document.createElement("LI")
li.innerText = el.innerText
list.appendChild(li)
}
})
<p>Orange</p>
<p>Grape</p>
<p>Apple</p>
<p>Not Apple</p>
<ul id="ulist"></ul>
It checks if each <p> has the word apple in it, and if so, it dynamically adds it to the list.
If you want to check if it's Apple just by itself, use ==, and if you want to make the search case-sensitive, remove the .toLowerCase() and change the word apple to Apple.
If you want to add every element, simply remove the if condition.
You should use += instead of =. Also forgot to close the list element (should be </li>). Also, for better performance you can first generate string for all the items the update the DOM only once.
You can check the text of the current element in each iteration based on which you can create items.
Demo:
<p>Orange</p>
<p>Grape</p>
<p>Apple</p>
<ul id=ulist>
</ul>
<script>
var i;
var x = document.getElementsByTagName("p");
var elString = "";
for (i = 0; i < x.length; i++) {
if(x[i].textContent.toLowerCase().includes('apple')){ // check if text contains the word
elString += "<li>"+x[i].textContent+"</li>";
}
}
document.getElementById("ulist").innerHTML = elString;
</script>
Using Document.querySelectorAll(), NodeList.prototype.forEach(),Document.getElementById(),
,Document.createElement() and RegExp.prototype.test().
const fruits = document.querySelectorAll("p"),
lists = document.getElementById("ulist");
fruits.forEach((fruit) => {
if (/apple/i.test(fruit.textContent)) {
const list = document.createElement("li");
list.textContent = fruit.textContent;
lists.append(list);
}
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Fruits</title>
</head>
<body>
<p>Orange</p>
<p>Grape</p>
<p>Apple</p>
<ul id="ulist"></ul>
</body>
</html>

Automatically load next image from array everytime user enters website

So this code selects random image whenever a person loads my website, how can I change the code so that images are selected sequentially from first to last everytime a person loads the website and then again resets to first image when the counter reaches the end?
P.s- The code works fine on hosting server, here it gives an error i don't know why.
window.onload = choosePic;
var myPix = new Array("https://i.imgur.com/LHtVLbh.jpg", "https://i.imgur.com/2YHazkp.png", "https://i.imgur.com/Uscmgqx.jpg");
function choosePic() {
var randomNum = Math.floor(Math.random() * myPix.length);
document.getElementById("myPicture").src = myPix[randomNum];
}
<!DOCTYPE html>
<html>
<head>
<title>Random Image</title>
<script src="thumb.js"></script>
</head>
<body>
<img src="images/spacer.gif" id="myPicture" alt="some image">
</body>
</html>
You can use localstorage to achieve this. When the user enters the website, you can do something like:
var pictureIndex = localstorage.getItem("pictureIndex");
But since it may be the user's first visit, it would be better to have:
var pictureIndex = localstorage.getItem("pictureIndex") || 0;
Then, you just increment the pictureIndex and perform a modulo operation (for the case when this is the last image)
pictureIndex = (pictureIndex + 1) % myPix.length;
To save this index, you can use
localStorage.setItem('pictureIndex', pictureIndex);
Next time when the user refreshes the page (or comes back), he will get the next picture in your array.
The final code should look like this:
window.onload = choosePic;
var myPix = new Array("https://i.imgur.com/LHtVLbh.jpg", "https://i.imgur.com/2YHazkp.png", "https://i.imgur.com/Uscmgqx.jpg");
function choosePic() {
var pictureIndex = window.localStorage.getItem("pictureIndex") || 0;
pictureIndex = (pictureIndex + 1) % myPix.length;
window.localStorage.setItem("pictureIndex", pictureIndex);
document.getElementById("imgid").innerHTML = pictureIndex;
document.getElementById("myPicture").src = myPix[pictureIndex];
}
<!DOCTYPE html>
<html>
<head>
<title>Random Image</title>
<script src="thumb.js"></script>
</head>
<body>
Press "Run" multiple times to cycle through the images.
Currently showing: <span id="imgid"></span>
<img src="images/spacer.gif" id="myPicture" alt="some image">
</body>
</html>
Note that the above code might not work here (but you can test it locally) due to some security restrictions from jsfiddle. A working version can be accessed >here<
function choosePic() {
var local_item = 0;
if(localStorage.getItem('pic_key')){
local_item = parseInt(intvlocalStorage.getItem('pic_key'));
}
if(local_item >= myPix.length){
local_item = 0;
}
localStorage.setItem('pic_key', local_item + 1);
document.getElementById("myPicture").src = myPix[local_item];
}
You can use LocalStorage to achieve this. When the user enters the website, you can store the key and increment it.
Use local storage to save the data you need [e.g. visited = 3(3rd time the same person visited your website)]
Your js code can be implemented like this:
window.onload = choosePic;
var myPix = new Array("https://i.imgur.com/LHtVLbh.jpg", "https://i.imgur.com/2YHazkp.png", "https://i.imgur.com/Uscmgqx.jpg");
function choosePic() {
if (localStorage.getItem('visited') == null)
{
document.getElementById("myPicture").src = myPix[0];
localStorage.setItem('visited', 1);
}
else if (localStorage.getItem('visited') >= myPix.length)
{
localStorage.setItem('visited', 0);
document.getElementById("myPicture").src = myPix[localStorage.getItem('visited')];
}
else
{
document.getElementById("myPicture").src = myPix[localStorage.getItem('visited')];
localStorage.setItem('visited', localStorage.getItem('visited') + 1);
}
}

How to make multiple random images appear upon clicking another using Javascript?

I'm currently trying to make an image that upon clicking, disappears and shows three random images. So far I thought maybe duplicating the clickable image twice and just making those invisible would work, so they would change to one of the random images and become visible after clicking the image. If you have any other idea of how this may work, I'd really like to know!
Also does anyone know how I could make it so that an image could only be used for one of the three spots, so that you always have three different random images next to each other.
Here is my JS and HTML:
var playerImg;
var playerImg2;
var playerImg3;
var playerArray = ["A1.png", "A2.png", "A3.png", "A4.png", "A5.png", "M1.png", "M2.png", "M3.png", "M4.png", "M5.png", "V1.png", "V2.png", "V3.png", "V4.png", "V5.png", "D1.png", "D2.png", "D3.png"];
function openPack() {
var randomPlayer = (Math.floor(Math.random() * 18) + 1);
playerImg = playerArray[randomPlayer - 1];
document.getElementById("pack").src = "image/" + playerImg;
var randomPlayer2 = (Math.floor(Math.random() * 18) + 1);
playerImg2 = playerArray[randomPlayer2 - 1];
document.getElementById("player2").src = "image/" + playerImg2;
var randomPlayer3 = (Math.floor(Math.random() * 18) + 1);
playerImg3 = playerArray[randomPlayer3 - 1];
document.getElementById("player3").src = "image/" + playerImg3;
}
document.querySelectorAll("img#player2")[0].addEventListener("click", openPack);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<img id="pack" src="image/pack.png" alt="Unopened pack">
<img id="player2" src="image/pack.png" alt="Place for a second player after the pack is opened">
<img id="player3" src="image/pack.png" alt="Place for a third player after the pack is opened">
<img id="veld" src="image/veld.png" alt="Football field with positions">
</body>
<script src="scripts/packs.js"></script>
</html>
Let me know if I forgot to tell something, and thank you!
Here new openPack function that will exclude duplicates
function openPack() {
var playerArraycopy = playerArray.slice();//getting new copy of initial input
function getRandomImg(){
return playerArraycopy.splice([Math.floor(Math.random() * playerArraycopy.length)],1)[0];//calculating a new random image and removing it from copy to exclude duplicates
}
document.getElementById("player2").src = "image/" + getRandomImg();
document.getElementById("pack").src = "image/" + getRandomImg();
document.getElementById("player3").src = "image/" + getRandomImg();
}
check Array.splice for more information

Jackhammers not changing on mouseover

I'm trying to get the image to change based on one second timer, but the image stays one the first object in the array
the code I have so far is
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Lab 8 - Jackhammer Man</title>
<script type="text/javascript">
var jackhammers = new Array();
jackhammers[0] = "<img src='Images/jackhammer0.gif'>";
jackhammers[1] = "<img src='Images/jackhammer1.gif'>";
jackhammers[2] = "<img src='Images/jackhammer2.gif'>";
jackhammers[3] = "<img src='Images/jackhammer2.gif'>";
jackhammers[4] = "<img src='Images/jackhammer4.gif'>";
jackhammers[5] = "<img src='Images/jackhammer5.gif'>";
jackhammers[6] = "<img src='Images/jackhammer6.gif'>";
jackhammers[7] = "<img src='Images/jackhammer7.gif'>";
jackhammers[8] = "<img src='Images/jackhammer8.gif'>";
jackhammers[9] = "<img src='Images/jackhammer9.gif'>";
jackhammers[10] = "<img src='Images/jackhammer10.gif'>";
var curJackhammer;
function bounce() {
var img = document.getElementsByTagName("img");
var i = 0 ;
for (i = 0; i<10;i++) {
if(jackhammers[i].src == img.src) {
if(i === jackkhammers.length) {
img.src = jackhammers[0].src;
break;
}
img.src = jackhammers[i+1].src;
break;
}
}
}
</script>
</head>
<body>
<img onMouseOver="setInterval(function(){bounce},1000);" onMouseOut="clearInternval(fuction(){bounce};" src="Images/jackhammer0.gif" id="hammer" name="hammerman" alt="Jackhammer Man">
</body>
</html>
The issue I'm coming across is the mouseover event will not activate, I am having trouble finding the error in my code as the debuggers I have aren't finding any. Any help trying to get the mouseover function of the image changing ever so often would be appreciated.
you have a typo if(i === jackkhammers.length)
jackhammers[x] has no src property so to get its value use it without .src
instead of
onMouseOver="setInterval(function(){bounce},1000);"
write:
onMouseOver="setInterval(function(){bounce();},1000);"
var img = document.getElementsByTagName("img");
This returns a NodeList, or an array of elements. You need to access the index of this element with [0]
Or better yet, use querySelector which returns the first element in a NodeList
You keep referring to the src property of items in the jackhammers array:
img.src = jackhammers[0].src;
even though items in that array are strings, not objects.
Also, there's a typo here:
if(i === jackkhammers.length) {
These kinds of errors would be immediately visible the with dev tools of your browser of choise. Put a breakpoint to where you suspect things go wrong and start investigating variables and your assumptions while stepping through the code.
See here: http://www.creativebloq.com/javascript/javascript-debugging-beginners-3122820
Updated code changed a few things around based on some advice from my mentor.
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Lab 8 - Jackhammer Man</title>
<script type="text/javascript">
var jackhammers = new Array(11);
jackhammers[0] = "Images/jackhammer0.gif";
jackhammers[1] = "Images/jackhammer1.gif";
jackhammers[2] = "Images/jackhammer2.gif";
jackhammers[3] = "Images/jackhammer3.gif";
jackhammers[4] = "Images/jackhammer4.gif";
jackhammers[5] = "Images/jackhammer5.gif";
jackhammers[6] = "Images/jackhammer6.gif";
jackhammers[7] = "Images/jackhammer7.gif";
jackhammers[8] = "Images/jackhammer8.gif";
jackhammers[9] = "Images/jackhammer9.gif";
jackhammers[10] = "Images/jackhammer10.gif";
var curJackhammer = 0;
var direction;
var begin;
function bounce(){
if(curJackhammer == 10)
curJackhammer = 0;
else
++curJackhammer;
document.getElementsByTagName("img")[0].src = jackhammers[curJackhammer].src;
if(curJackhammer == 0)
direction = "up";
else if(curJackhammer == 10)
direction = "down";
document.getElementsByTagName("img")[0].src = jackhammers[curJackhammer];
}
function startBouncing(){
if (begin)
clearInterval (begin);
begin = setInterval("bounce()",90);
}
</script>
</head>
<body>
<h1>Jackhammer Man</h1>
<p><img onMouseOver="startBouncing();" onMouseOut="clearInterval(begin);" src="Images/jackhammer0.gif" height="113" width="100" alt="Image of a man with a jackhammer." /></p>
</body>
</html>
>
Used firebug to step into code, works once I set into it but simply putting a mouse over nothing happens.

Categories

Resources