Javascript not hiding button on last image - javascript

I have a JSFiddle that shows my code now:
https://jsfiddle.net/qtu1xgw3/2/
Basically there is an image button (pink flower) and then there are 4 images that change when the button is clicked.
Now the issue is that I want the button to hide when I get to the last image. Right now I need to click the button twice to get it to hide on the last image. But I want with the last click of the button to hide it at the same time that the last image in the gallery is shown.
One of the images is in the html part of the code, which might be what causes this issue, I think, but I'm not sure how to do this differently without breaking the code?
(random images from google used for the sake of testing)
HTML:
<div class="test">
<div class="desc">
<h2 id="title_text">test1</h2>
<p id="under_text">test2</p>
</div>
<div id="pink">
<img src="https://images.vexels.com/media/users/3/234325/isolated/lists/cba2167ec09abeeee327ffa0f994151b-detailed-flower-illustration.png" onclick="imagefun()"></div>
<div class="game">
<img src="https://images.vexels.com/media/users/3/143128/isolated/lists/2a84565e7c9642368346c7e6317fa1fa-flat-flower-illustration-doodle.png" id="getImage"></div>
</div>
CSS:
.game img {
width: 300px;
height: auto;
}
.test {
display: flex;
flex-direction: row;
}
JS:
var counter = 0,
gallery = ["https://cdn.cloudflare.steamstatic.com/steamcommunity/public/images/apps/914750/aab494aa7cde1991d0a86cc28ec6debdbee37d7f.jpg", "https://api.assistivecards.com/cards/gardening/flowers.png", "https://i.pinimg.com/474x/7d/10/75/7d1075cf259131c942037683d2243bb0.jpg"],
imagefun = function () {
if (counter >= gallery.length) {
document.getElementById("title_text").innerHTML = "test3"; document.getElementById("under_text").innerHTML = "test4"; document.getElementById("pink").style.display = "none";
}
else{
document.getElementById("getImage").src = gallery[counter];
counter++;
}
};

I have made some change to your code. It will help you.
var counter = 0,
gallery = ["https://cdn.cloudflare.steamstatic.com/steamcommunity/public/images/apps/914750/aab494aa7cde1991d0a86cc28ec6debdbee37d7f.jpg", "https://api.assistivecards.com/cards/gardening/flowers.png", "https://i.pinimg.com/474x/7d/10/75/7d1075cf259131c942037683d2243bb0.jpg"],
imagefun = function () {
if (counter == gallery.length -1) {
document.getElementById("getImage").src = gallery[counter];
document.getElementById("pink").style.display = "none";
}
else{
document.getElementById("getImage").src = gallery[counter];
counter++;
}
};

try this
Evaluate when the counter is equal to the size of your array if so then do the job you want
imagefun = function () {
if(counter==gallery.length)
{
document.getElementById("getImage").style.display = "none";
}
if (counter >= gallery.length) {
document.getElementById("title_text").innerHTML = "test3";
document.getElementById("under_text").innerHTML = "test4";
document.getElementById("pink").style.display = "none";
}
else{
document.getElementById("getImage").src = gallery[counter];
counter++;
}
};

The issue is that you increment your counter after the counter >= gallery.length check.
The correct solution is:
const gallery = [
"https://cdn.cloudflare.steamstatic.com/steamcommunity/public/images/apps/914750/aab494aa7cde1991d0a86cc28ec6debdbee37d7f.jpg",
"https://api.assistivecards.com/cards/gardening/flowers.png",
"https://i.pinimg.com/474x/7d/10/75/7d1075cf259131c942037683d2243bb0.jpg",
];
let counter = 0;
document.getElementById("getImage").src = gallery[counter];
function imagefun() {
counter += 1;
document.getElementById("getImage").src = gallery[counter];
if (counter >= gallery.length - 1) {
document.getElementById("title_text").innerHTML = "test3";
document.getElementById("under_text").innerHTML = "test4";
document.getElementById("pink").style.display = "none";
}
};

Related

How do I detect, with JavaScript, if an image was pasted or dropped into a contenteditable area?

I have a script that prevents the user from pasting, or dropping dragged images into a contenteditable area. When the user tries to do one of those two things, I want an alert to tell him he cannot do that. I tried adding alert("custom message") right before the last break. But it gets triggered in both cases (pasting and dropping). How can I have two different alerts: one for when the user pastes an image ("you cannot paste images here"), and another for when the user drops a dragged image ("you cannot drop images here", within my code?
https://jsfiddle.net/36cfdpoh/
window.onload = function() {
document.getElementById("editDiv").oninput = function() {
var thisElement = this;
var currentElementChildren, currentElementChildrenLength;
var elements = this.children;
var elementsLength = elements.length;
if (elementsLength > 0) {
for (i = 0; i < elementsLength; i++) {
if (elements[i].tagName == "IMG") {
thisElement.children[i].remove();
break;
} else {
currentElementChildren = elements[i].children;
currentElementChildrenLength = currentElementChildren.length;
if (currentElementChildrenLength > 0) {
for (ii = 0; ii < currentElementChildrenLength; ii++) {
if (currentElementChildren[ii].tagName == "IMG") {
thisElement.children[i].children[ii].remove();
alert("you cannot drop images here");
break;
}
}
}
}
}
}
}
}
#editDiv {
width: 250px;
height: 50px;
border: solid 1px #000;
margin-bottom: 20px;
}
img {
width: 250px;
}
<div id="editDiv" contenteditable="true">
<p>Try to drop or paste that image here.</p>
</div>
<img src="https://i7.pngguru.com/preview/134/138/533/star-golden-stars.jpg">
There are two solutions to this. Using the input event or using drop and paste events:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" type="text/css" href="styles.css">
<title>Image phobia</title>
</head>
<body>
<h1>Image phobia</h1>
<div id="editDiv" contenteditable="true">
<p>Try to drop or paste that image here.</p>
</div>
<img height="100" width="100" src="https://i7.pngguru.com/preview/134/138/533/star-golden-stars.jpg">
<img height="100" width="100" src="https://i7.pngguru.com/preview/134/138/533/star-golden-stars.jpg">
<script src="main.js" />
</body>
</html>
input event solution:
main.js
"use strict";
(function() {
window.addEventListener("load", () => {
const editDiv = document.getElementById("editDiv");
// return a message depending on input type
function alertMessage(type) {
switch (type) {
case "insertFromPaste":
return "You can't paste images here";
case "insertFromDrop":
return "You can't drop images here";
}
}
// recursive function to delete image from an element's children
function removeImages(children) {
let hadImage = false;
for (let i = children.length - 1; i >= 0; i--) {
const child = children[i];
if (child.tagName === "IMG") {
child.remove();
hadImage = true;
continue;
}
if (child.children.length) {
hadImage = removeImages(child.children);
if (hadImage) {
break;
}
}
}
return hadImage;
}
function preventImageInput(e) {
const inputType = e.inputType;
if (inputType === "insertFromDrop" || inputType === "insertFromPaste") {
if (e.target.children.length) {
const hadImage = removeImages(e.target.children);
if (hadImage) {
alert(alertMessage(inputType));
}
}
}
}
editDiv.addEventListener("input", preventImageInput);
});
})();
drop and paste events solution:
main.js
"use strict";
(function() {
window.addEventListener("load", () => {
const editDiv = document.getElementById("editDiv");
// return message depending on event type
function alertMessage(type) {
switch (type) {
case "paste":
return "You can't paste images here";
case "drop":
return "You can't drop images here";
}
}
function preventImageInput(e) {
// you must use setTimeout because when both the paste or drop events are fired
// the content isn't changed yet and you won't have access to the new content
setTimeout(() => {
const images = e.target.querySelectorAll("img");
if (images.length) {
for (let i = images.length - 1; i >= 0; i--) {
const image = images[i];
image.remove();
}
alert(alertMessage(e.type));
}
});
}
editDiv.addEventListener("paste", preventImageInput);
editDiv.addEventListener("drop", preventImageInput);
});
})();
You can separately attach paste & drop event to dom and then check which one is firing

Settime out messing with onclick event in javascript

im trying to create a automatic image slider which also responds to an onclick function, for some odd reason the onclick event is pretty much doing nothinig i suspect its cause of the settime out as javascript is single threaded but im no master at javascript! could someone please tell me what i'm doing wrong stuck with this for the past two days! thank you!
var i = 0;
var starterimages= [];
var time = 3000;
var eventaction=0;
var timeoutId;
starterimages[0] = "https://i.pinimg.com/236x/f4/92/39/f492399e154bd9f564d7fc5299c19911--purple-rain-deep-purple.jpg";
starterimages[1] = "https://image.shutterstock.com/image-photo/purple-butterfly-isolated-on-white-260nw-44004850.jpg";
starterimages[2] = "https://www.birdscanada.org/images/inbu_norm_q_townsend.jpg";
var nextbutton=document.querySelector("#rightbutton");
nextbutton.addEventListener("click",rightbuttonclick);
var prevbutton=document.querySelector("#leftbutton");
nextbutton.addEventListener("click",leftbuttonclick);
function rightbuttonclick()
{
eventaction=1;
clearTimeout(timeoutId);
}
function leftbuttonclick()
{
eventaction=2;
clearTimeout(timeoutId);
}
function changeImg(){
document.getElementById('startersliders').src = starterimages[i];
if(eventaction==1)
{
i++;
if(i < starterimages.length - 1)
{document.getElementById('startersliders').src = starterimages[i];
eventaction=0;}
else
{
i=0;
document.getElementById('startersliders').src = starterimages[i];
eventaction=0;
}
}
else if(eventaction==2)
{
i--;
if(i== - 1)
{
i=3;
document.getElementById('startersliders').src = starterimages[i];
eventaction=0;
}
else
{
document.getElementById('startersliders').src = starterimages[i];
eventaction=0;
}
}
else if(eventaction==0){
if(i < starterimages.length - 1){
i++;
}
else {
i = 0;
}
}
// Run function every x seconds
timeoutId = setTimeout("changeImg()", time);
}
// Run function when page loads
window.onload=changeImg;
#staratersliders {
width: 10%;
height: 10%;
position: relative;
margin: 0% 0% 0% 0%;
}
<button class="button button3" id="leftbutton"> previous</button>
<img id="startersliders" />
<button class="button button3" id="rightbutton">next</button>
I got it all working in Firefox 51, buttons included. Just paste the whole thing in a blank page and save it with an .htm or .html extension.
<!DOCTYPE=HTML><html><meta charset="UTF-8">
<script>
var i = 0;
var starterimages= [];
var time = 3000;
var eventaction=0;
var timeoutId;
starterimages[0] = "https://i.pinimg.com/236x/f4/92/39/f492399e154bd9f564d7fc5299c19911--purple-rain-deep-purple.jpg";
starterimages[1] = "https://image.shutterstock.com/image-photo/purple-butterfly-isolated-on-white-260nw-44004850.jpg";
starterimages[2] = "https://www.birdscanada.org/images/inbu_norm_q_townsend.jpg";
function rightbuttonclick() {
eventaction = 1;
clearTimeout(timeoutId);
changeImg();
}
function leftbuttonclick() {
eventaction = 2;
clearTimeout(timeoutId);
changeImg();
}
function changeImg() {
if (eventaction == 1) {
if (i < starterimages.length - 1) {
i++;
document.getElementById('startersliders').src=starterimages[i];
eventaction = 0;
} else {
i = 0;
document.getElementById('startersliders').src=starterimages[i];
eventaction = 0;
}
} else if (eventaction == 2) {
i--;
if (i < 0) {
i = 2;
document.getElementById('startersliders').src=starterimages[i];
eventaction = 0;
} else {
document.getElementById('startersliders').src=starterimages[i];
eventaction = 0;
}
} else {
if (i < starterimages.length - 1) {
i++;
} else {
i = 0;
};
document.getElementById('startersliders').src=starterimages[i];
eventaction = 0;
}
timeoutId=setTimeout("changeImg()", time);
}
</script>
<style>
#startersliders {width: 10%;height: 10%;position: relative;margin: 0% 0% 0% 0%;}
</style>
<body onload="changeImg();">
<button class="button button3" id="leftbutton">previous</button>
<img id="startersliders">
<button class="button button3" id="rightbutton">next</button>
<script>
var nextbutton=document.querySelector("#rightbutton");
nextbutton.addEventListener("click",rightbuttonclick);
var prevbutton=document.querySelector("#leftbutton");
prevbutton.addEventListener("click",leftbuttonclick);
</script>
</body>
</html>
It won't work because this:
setTimeout("changeImg()", time);
Is invalid syntax for setTimeout. To fix it, just do this:
setTimeout(changeImg, time);
var nextbutton=document.querySelector("#rightbutton");
nextbutton.addEventListener("click",rightbuttonclick);
var prevbutton=document.querySelector("#leftbutton");
nextbutton.addEventListener("click",leftbuttonclick);
I copy/pasted the code into my machine and the above came up null because they need to be between script tags at the bottom of the body of the doc.
When the parser sees those at the top, it doesn't know what #rightbutton and #leftbutton are because it hasn't parsed the html in the body section yet so it comes back as a null element
just move them to the bottom of the body section after the html and put script /script tags around them and see what happens
You need to do both of the above, what Matthew Herbst said is correct and what Jack Bashford said is correct. Create a variable for the setTimeout
var mytimeinverval;
var mytimer;
mytimer=setTimeout(myfunctionname,mytimeinterval);
The function name inside the setTimeout doesn't get quotes or parenthesis.
If you put parenthesis in, it might fire instantly or who knows?
It still recognizes myfunctionname as a function without the parenthesis.
Putting quotes around it makes it a string-won't work in my experience.
I don't want credit, they answered it, just letting you know to do both.

How to make a click on the button change its color in Javascript

I am making a small game where in I have 50 buttons and when I click on any one of the button, its color changes and amongst them, I have one button which is blue in color. If the player clicks on that blue button, he is a winner. He will be given only three chances. I have used a button eventhandler that takes the color id and accordingly changes the color. But the colorId from the count is 51 and not amongst the 1 - 50 buttons. What is wrong?
<html>
<head>
<title>Blue-Box</title>
</head>
<body>
<script>
var colorId;
var button;
var noOfTries = 3;
function createButtons() {
colorId = 0;
for (var index = 0; index <= 50; index++) {
button = document.createElement("button");
button.innerHTML = "box " + index;
button.id = colorId;
button.setAttribute("value", colorId);
button.setAttribute("text", colorId);
button.style.fontFamily = "Times New Roman";
button.style.backgroundColor = "#C0C0C0";
button.style.fontSize = "15px";
document.body.appendChild(button);
colorId++;
button.addEventListener("click", selectColor);
}
}
function selectColor() {
console.log((colorId));
console.log("button click");
if (noOfTries > 0) {
noOfTries = noOfTries - 1;
if ((colorId) <= 24) {
console.log("red color")
document.getElementById(colorId).style.backgroundColor = "#BC8F8F";
}
else if (colorId == 25) {
console.log("blue color")
document.getElementById(colorId).style.backgroundColor = "#0099CC";
document.write("You Won the game");
noOfTries = 3;
}
else if (colorId > 25 && colorId < 51) {
document.getElementById(colorId).style.backgroundColor = "#008080";
}
}
else {
document.write("Your attempts have finished");
}
}
</script>
<div id="divbox">
<button id="buttonbox" onclick="createButtons()">Click to start the Game</button>
</div>
</body>
</html>
Hope this helps you.
<html>
<head>
<title>Blue-Box</title>
</head>
<body>
<script>
var colorId = 1;
var button;
var lives = 0;
function createButtons(){
colorId=0;
for(var index=1;index<=50;index++){
button=document.createElement("button");
button.innerHTML="box "+index;
button.id=colorId;
button.setAttribute("value",colorId);
button.setAttribute("text",colorId);
button.style.fontFamily="Times New Roman";
button.style.backgroundColor="#C0C0C0";
button.style.fontSize="15px";
button.addEventListener("click", function(){
selectColor(this.id);
})
document.getElementById("btnbox").appendChild(button);
colorId++;
}
}
function selectColor(colorId){
lives++;
if(lives < 4){
if (colorId<=24){
document.getElementById(colorId).style.backgroundColor="#BC8F8F";
}
else if (colorId==25){
document.getElementById(colorId).style.backgroundColor="#0099CC";
alert("Winner");
location.reload();
}
else{
document.getElementById(colorId).style.backgroundColor="limegreen";
}
}
else if(lives == 4){
alert("Game over!");
location.reload();
}
}
</script>
<div id="divbox">
<button id="buttonbox" onclick="createButtons()">Click to start the Game</button>
</div>
<div id="btnbox">
</div>
</body>
// first add a global variable
var noOfTries = 3;
function selectColor() {
// check if greater than 3
if(noOfTries > 0) {
// if yes, then decrement
noOfTries = noOfTries - 1;
// continue with the color change
if (colorId<=24) {
document.getElementById(colorId).style.backgroundColor="#BC8F8F";
}
else if (colorId==25) {
document.getElementById(colorId).style.backgroundColor="#0099CC";
}
else {
document.getElementById(colorId).style.backgroundColor="limegreen";
}
}
}
Use:
button.addEventListner("click",function() {
button.style.backgroundColor=nextColor;
})

setInterval loop not working

I am creating a simple image slide with JavaScript, but when I loop through all the images, I can not reset the loop:
var images = document.querySelectorAll(".slide-img");
var index = 0;
var time = 1000;
function reset(){
for(var i = 0; i <= 3; i++){
images[i].style.display = 'none';
images[0].style.display = 'block';
}
}
reset();
var looper = setInterval(function(){
index++;
images[index].style.display = 'block';
if(index == 3){
index = 0;
images[index].style.display = 'block';
//or calling reset() again.
}
}, 1000);
After setting all the image display:noneexcept the first one, I tried calling setInterval for looping all my images, but problem occurs when the index is 3. I am calling the reset() function and it is not working?
Your code has a few problems.
The code inside the if statement doesn't reset all the images to hidden. So you would need to call reset function instead
Your reset function doesn't reset the index.
You should set index 0 to block once, and then loop through the rest instead of setting index 0 to block in each iteration.
Because you reset when index == 3, you will never see the last image. You should reset on the following iteration to ensure that each image is visible for one second.
See my example below.
var images = document.querySelectorAll(".slide-img");
var index = 0;
var time = 1000;
function reset(){
index = 0;
images[0].style.display = 'block';
for(var i = 1; i < images.length; i++){
images[i].style.display = 'none';
}
}
reset();
setInterval(function(){
index++;
if(index >= images.length){
reset();
} else {
images[index].style.display = 'block';
}
}, 1000);
.container {
display: flex;
}
.slide-img {
width: 100px;
height: 100px;
}
<div class="container">
<div class="slide-img" style="background: red"></div>
<div class="slide-img" style="background: blue"></div>
<div class="slide-img" style="background: green"></div>
<div class="slide-img" style="background: purple"></div>
</div>
If you have other question on why my code is different than yours, ask in the comments. But I think the code should be clear and understandable.

Changing div time

<style>
#main div {
display: none;
}
</style>
<div id="main">
<div>first</div>
<div>second</div>
<div>third</div>
</div>
<script>
var divElems = [].slice.call(document.querySelectorAll('#main div')),
main = document.querySelector('#main'), i = 0;
setInterval(function f() {
var item = divElems[i % divElems.length];
item.style.display = 'block';
i++;
}, 3000);
</script>
Can you please tell how to make within #main show up on the queue without stopping? Initially, they are hidden.
Element first, second and third should appear in sequence, every 3 seconds
First shows a block
<div>first</div>
then instead
<div>second</div>
and then
<div>third</div>
I have updated my answer again after your comment. Is this what you are looking for?
var divElems = [].slice.call(document.querySelectorAll('#main div')),
main = document.querySelector('#main'),
i = 0;
divElems[0].style.display = 'block';
setInterval(function f() {
var item = divElems[i % divElems.length];
item.style.display = 'none';
i++;
item = divElems[i % divElems.length];
item.style.display = 'block';
}, 3000);

Categories

Resources