Stumped on IF statement in javascript - javascript

I can only let the user upload a certain amount of pictures so I am trying to increment a variable 'j' three times before disabling the upload picture button. I know j is incrementing because I printed it out in an alert box for each increment. I really want to know how this is not working. if you have a more elegant solution I am happy with that too.
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
</style>
</head>
<body>
<input id="browse" type="file" onchange="previewFiles()" multiple>
<div id="preview"></div>
<script>
var j = 0;
if (j < 3){
function previewFiles() {
j++;
alert(j);
var preview = document.querySelector('#preview');
var files = document.querySelector('input[type=file]').files;
function readAndPreview(file) {
// Make sure `file.name` matches our extensions criteria
if ( /\.(jpe?g|png|gif)$/i.test(file.name) ) {
var reader = new FileReader();
reader.addEventListener("load", function () {
var image = new Image();
image.height = 100;
image.title = file.name;
image.src = this.result;
preview.appendChild( image );
}, false);
reader.readAsDataURL(file);
}
}
if (files) {
[].forEach.call(files, readAndPreview);
}
}
}
else {
alert("I want to get in here");
document.getElementById("browse").disabled = true;
}
</script>
</body>

The if block is outside of your function, so when previewFiles is called, the if block is not executed. Try this:
var j = 0;
function previewFiles() {
if (j < 3) {
j++;
alert(j);
var preview = document.querySelector('#preview');
var files = document.querySelector('input[type=file]').files;
function readAndPreview(file) {
// Make sure `file.name` matches our extensions criteria
if (/\.(jpe?g|png|gif)$/i.test(file.name)) {
var reader = new FileReader();
reader.addEventListener("load", function() {
var image = new Image();
image.height = 100;
image.title = file.name;
image.src = this.result;
preview.appendChild(image);
}, false);
reader.readAsDataURL(file);
}
}
if (files) {
[].forEach.call(files, readAndPreview);
}
} else {
alert("I want to get in here");
document.getElementById("browse").disabled = true;
}
}
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
</style>
</head>
<body>
<input id="browse" type="file" onchange="previewFiles()" multiple>
<div id="preview"></div>
</body>

Related

I have trouble hiding elements in my game if they don't match

I am working on a memory game and I asked a previous question earlier which was answered. I've had this problem and I haven't been able to find a solution with effort. So it's a memory game and when the cards are clicked, they are pushed into an array which can hold two elements at max (you can only click two cards) and then the two elements' frontSrc is checked if they are the same. I set that using an expando property. If so, have them visible and then clear the array so I can do more comparisons. However, it doesn't seem to be working as intended. I'll attach a video below. I've tried using timeout to set the length again, but that didn't work. It works for the first cards, but the other ones after that, it doesn't work.
Here is my code.
<!DOCTYPE html>
<!--
Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
Click nbfs://nbhost/SystemFileSystem/Templates/Other/html.html to edit this template
-->
<html>
<head>
<title>TODO supply a title</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
.card{
width: 35%;
}
#cards{
display: grid;
grid-template-columns:25% 25% 25% 25%;
row-gap: 25px;
}
</style>
</head>
<body onload="init()">
<section id="cards">
</section>
<script>
var arrCards = [];
var arrShowedCards = [];
//appendElements();
function init(){
createCards();
shuffleCards();
appendElements();
}
function createCards(){
var arrCardNames = ["Mouse","Penguin","Pop","Mouse","Penguin","Pop"];
for(var i = 0; i<6; i++){
var card = document.createElement("IMG");
card.src = "Images/red_back.png";
card.className = "card";
card.frontSrc = "Images/" + arrCardNames[i] + ".png";
card.id = "card" + i;
card.addEventListener("click", showCard);
document.getElementById("cards").appendChild(card);
arrCards.push(card);
}
}
function shuffleCards(){
for (let i = arrCards.length-1; i > 0; i--)
{
const j = Math.floor(Math.random() * (i + 1));
const temp = arrCards[i];
arrCards[i] = arrCards[j];
arrCards[j] = temp;
}
return arrCards;
}
function appendElements(){
for(var i = 0; i<arrCards.length; i++){
document.getElementById("cards").appendChild(arrCards[i]);
}
}
function showCard(){
var sourceString = "Images/red_back.png";
this.src = this.frontSrc;
arrShowedCards.push(this);
if(arrShowedCards.length === 2){
if(arrShowedCards[0].frontSrc === arrShowedCards[1].frontSrc){
console.log("Match!");
arrShowedCards = [];
}
else{
console.log("No match!");
setTimeout(function(){
arrShowedCards[0].src = sourceString;
arrShowedCards[1].src = sourceString;
}, 1000);
}
}
}
</script>
</body>
</html>
I am not sure how come it doesn't work for it for the other cards.
Here is the video.
https://drive.google.com/file/d/1aRPfLALHvTKjawGaiRgD1d0hWQT3BPDQ/view
If anyone finds a better way to approach this, let me know.
Thanks!
I think when not match, you need to reset arrShowedCards otherwise its length will be greater than 2 forever.
function showCard() {
var sourceString = "Images/red_back.png";
this.src = this.frontSrc;
arrShowedCards.push(this);
if (arrShowedCards.length === 2) {
var a = arrShowedCards[0], b = arrShowedCards[1];
arrShowedCards.length = 0;
if (a.frontSrc === b.frontSrc) {
console.log("Match!");
} else {
console.log("No match!");
setTimeout(function () {
a.src = sourceString;
b.src = sourceString;
}, 1000);
}
}
}

Need to solve problem with asynchronous code

I made a small game where there are 3 pictures of chests, and you have one attempt to choose a chest with a prize.
But the problem is with the asynchronous code, a notification of defeat or victory is displayed faster than the desired picture is put in the right place, After the message, a function that puts all the chests closed that also does not allow the picture to take its place.
var count=0;
var imgArray = new Array();
imgArray[0] = new Image();
imgArray[0].src ='https://i.pinimg.com/originals/ae/f7/15/aef715f93eadcdf77c4dfa3baf5859ad.jpg'
imgArray[1] = new Image();
imgArray[1].src = "https://previews.123rf.com/images/gl0ck33/gl0ck331106/gl0ck33110600002/9781614-wooden-chest-with-gold-coins.jpg";
imgArray[2] = new Image();
imgArray[2].src = "https://i.pinimg.com/originals/94/09/6b/94096bf738837c16582902d281c520bc.jpg";
var images = document.getElementsByTagName("img");
var k = Math.floor(Math.random() * 3) + 1;
console.log("Winning number " + k);
for (var i = 0; i < images.length; i++) {
images[i].addEventListener("click", function(e) {
count++;
console.log("Count " + count);
if(this.id == k){
count=0;
this.src = imgArray[1].src;//here picture with a gift
alert("You Win");// here problem,alert Faster than the picture above
TryAgain();//And this function is faster to put pictures with closed chests
return;
} else {
this.src = imgArray[0].src;//picture empty chest
}
if (count >= 1) {
count = 0;
alert("You lose!!!");//alert Faster than the picture above
TryAgain();
return;
}
}, false);
}
function TryAgain(e) {
for (var i = 0; i < images.length; i++){
images[i].src = imgArray[2].src;//picture with close chest
k = Math.floor(Math.random() * 3) + 1;
}
console.log(k);
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<img width="300px" height="300px" src="https://i.pinimg.com/originals/94/09/6b/94096bf738837c16582902d281c520bc.jpg" id="1">
<img width="300px" height="300px" src="https://i.pinimg.com/originals/94/09/6b/94096bf738837c16582902d281c520bc.jpg" id="2">
<img width="300px" height="300px" src="https://i.pinimg.com/originals/94/09/6b/94096bf738837c16582902d281c520bc.jpg" id="3">
<button id="btn" onclick="TryAgain()">Try Again</button>
</body>
</html>
Answer:
You need to wait for the images to get done loading before running alert.
alert completely halts the processing of code. Therefore if the image isn't loaded before it is executed you're not going to see the change occur.
A simple pattern to do this would be:
let self = this;
this.src = imgArray[1].src;
this.onload = function() {
alert("You Win");
self.onload = undefined;
TryAgain();
}
return;
Example:
var count=0;
var imgArray = new Array();
imgArray[0] = new Image();
imgArray[0].src ='https://i.pinimg.com/originals/ae/f7/15/aef715f93eadcdf77c4dfa3baf5859ad.jpg'
imgArray[1] = new Image();
imgArray[1].src = "https://previews.123rf.com/images/gl0ck33/gl0ck331106/gl0ck33110600002/9781614-wooden-chest-with-gold-coins.jpg";
imgArray[2] = new Image();
imgArray[2].src = "https://i.pinimg.com/originals/94/09/6b/94096bf738837c16582902d281c520bc.jpg";
var images = document.getElementsByTagName("img");
var k = Math.floor(Math.random() * 3) + 1;
console.log("Winning number " + k);
for (var i = 0; i < images.length; i++) {
images[i].addEventListener("click", function(e) {
let self = this;
count++;
console.log("Count " + count);
if(this.id == k){
count=0;
this.src = imgArray[1].src;//here picture with a gift
this.onload = function() {
alert("You Win");// here problem,alert Faster than the picture above
self.onload = undefined;
TryAgain();//And this function is faster to put pictures with closed chests
}
return;
} else {
this.src = imgArray[0].src;//picture empty chest
this.onload = function() {
alert("You Lose");// here problem,alert Faster than the picture above
self.onload = undefined;
TryAgain();//And this function is faster to put pictures with closed chests
}
return;
}
}, false);
}
function TryAgain(e) {
for (var i = 0; i < images.length; i++){
images[i].src = imgArray[2].src;//picture with close chest
k = Math.floor(Math.random() * 3) + 1;
}
console.log(k);
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<img width="300px" height="300px" src="https://i.pinimg.com/originals/94/09/6b/94096bf738837c16582902d281c520bc.jpg" id="1">
<img width="300px" height="300px" src="https://i.pinimg.com/originals/94/09/6b/94096bf738837c16582902d281c520bc.jpg" id="2">
<img width="300px" height="300px" src="https://i.pinimg.com/originals/94/09/6b/94096bf738837c16582902d281c520bc.jpg" id="3">
<button id="btn" onclick="TryAgain()">Try Again</button>
</body>
</html>
Images do not appear as soon as you set this.src
They appear when the browser is ready to show them, which may take some time.
Perhaps you can use the "load" event listener? This will fire once the image is visible. At that stage you can do the alert?
images[i].addEventListener("load", function(e) {
// This will run only once the image is loaded (i.e. visible)
} )

Javascript Next and Previous images

Code is supposed to show next image when clicking on next arrow and previous image when clicked on previous arrow. It does not work though. (error occurs while assigning img.src=imgs[this.i]; it says Cannot set property 'src' of null
at collection.next) .
Javascript code :
var arr = new collection(['cake.png', 'image2.png', 'image3.png', 'image1.png']);
function collection(imgs) {
this.imgs = imgs;
this.i = 0;
this.next = function(element) {
var img = document.getElementById('element')
this.i++;
if (this.i == imgs.length) {
this.i = 0;
}
img.src = imgs[this.i].src;
}
this.prev = function(element) {
var img = document.getElementById('element');
this.i--;
if (this.i < 0) {
this.i = imgs.length - 1;
}
img.src = imgs[this.i].src;
}
}
<!DOCTYPE html>
<html>
<head>
<title>photos</title>
<script src="photos.js"></script>
</head>
<body>
<input type='button' value='<' name='next' onclick="arr.next('mainImg')" />
<img id='mainImg' src="cake.png">
<input type='button' value='>' name='prev' onclick="arr.prev('mainImg')" />
</body>
</html>
Not using jquery. I do not have enough experience in js either. Thank you for your time
You had three mistakes:
You referenced the images as img.src = imgs[this.i].src; and you just had an array of strings, not an array of objects with a src property. img.src = imgs[this.i]; is the correct way to get the URL.
You used
var img = document.getElementById('element');
when you should have used
var img = document.getElementById(element);
element is an argument coming from your onclick event. It holds the id of your image that you should be using. "element" is just a string. You try to find an element with id equal to element which doesn't exist.
Edit: You should also use < and > to represent < and >. Otherwise your HTML might get screwed up. More on that here.
var arr = new collection(['http://images.math.cnrs.fr/IMG/png/section8-image.png', 'https://www.w3.org/MarkUp/Test/xhtml-print/20050519/tests/jpeg444.jpg', "http://saturnraw.jpl.nasa.gov/multimedia/images/raw/casJPGFullS72/N00183828.jpg"]);
function collection(imgs) {
this.imgs = imgs;
this.i = 0;
this.next = function(element) {
var img = document.getElementById(element);
this.i++;
if (this.i >= imgs.length) {
this.i = 0;
}
img.src = imgs[this.i];
};
this.prev = function(element) {
var img = document.getElementById(element);
this.i--;
if (this.i < 0) {
this.i = imgs.length - 1;
}
img.src = imgs[this.i];
};
this.next("mainImg"); // to initialize with some image
}
<!DOCTYPE html>
<html>
<head>
<title>photos</title>
<script src="photos.js"></script>
</head>
<body>
<input type='button' value='<' name='next' onclick="arr.next('mainImg')" />
<img id='mainImg' src="cake.png">
<input type='button' value='>' name='prev' onclick="arr.prev('mainImg')" />
</body>
</html>
This is how I'd personally do it:
var myCollection = new Collection([
"http://images.math.cnrs.fr/IMG/png/section8-image.png",
"https://www.w3.org/MarkUp/Test/xhtml-print/20050519/tests/jpeg444.jpg",
"http://saturnraw.jpl.nasa.gov/multimedia/images/raw/casJPGFullS72/N00183828.jpg"
], "mainImg");
document.getElementById("next_btn").onclick = function() {
myCollection.next();
};
document.getElementById("prev_btn").onclick = function() {
myCollection.prev();
}
function Collection(urls, imgID) {
var imgElem = document.getElementById(imgID);
var index = 0;
this.selectImage = function() {
imgElem.src = urls[index];
};
this.next = function() {
if (++index >= urls.length) {
index = 0;
}
this.selectImage();
};
this.prev = function(element) {
if (--index < 0) {
index = urls.length - 1;
}
this.selectImage();
};
// initialize
this.selectImage();
}
<!DOCTYPE html>
<html>
<head>
<title>photos</title>
<script src="photos.js"></script>
</head>
<body>
<input id="next_btn" type='button' value='<' />
<img id='mainImg'>
<input id="prev_btn" type='button' value='>' />
</body>
</html>
Why sending string into arr.next('mainImg') function ?
your img element always have the same id, only change src.
and document.getElementById(element) is also the same img element.
html: <img id='mainImg' src="cake.png">
js: document.getElementById('mainImg')
consider img element as a container, and id is it's identifiler.
var start_pos = 0;
var img_count = document.getElementsByClassName('icons').length - 1;
var changeImg = function(direction){
pos = start_pos = (direction == "next")? (start_pos == img_count)? 0 : start_pos+1 : (start_pos == 0)? img_count : start_pos-1;
console.log(pos)
}
document.getElementById('left').onclick = function(){ changeImg("previous"); }
document.getElementById('right').onclick = function(){ changeImg("next"); }

How can i make a HTML button run three functions one after another

My code has three functions. I want one button to run function one when pressed the first time then function 2 when pressed the second time function 3 when pressed the third time and then for it to reset.
Here's my code:
<!DOCTYPE html>
<html>
<head>
<script>
var red = "https://s23.postimg.org/bo5a8hzsr/red_jpg.png"
var yellow = "https://s24.postimg.org/dodxgn305/yellow.png"
var green = "https://s29.postimg.org/5ljr1ha3r/green.png"
var lights =[red,yellow,green]
function changered()
{
var img = document.getElementById("light");
img.src= lights[0];
return false;
}
function changeyellow()
{
var img = document.getElementById("light");
img.src= lights[1];
return false;
}
function changegreen()
{
var img = document.getElementById("light");
img.src= lights[2];
return false;
}
</script>
</head>
<body>
<button id="sequence" onclick="changeyellow" onclick="changered" onclick="changegreen">sequence</button>
<br><br><br>
<img id="light" src="https://s29.postimg.org/5ljr1ha3r/green.png" />
</body>
</html>
You can use only one function and a global variable that contains the current color like this :
<!DOCTYPE html>
<html>
<head>
<script>
var red = "https://s23.postimg.org/bo5a8hzsr/red_jpg.png"
var yellow = "https://s24.postimg.org/dodxgn305/yellow.png"
var green = "https://s29.postimg.org/5ljr1ha3r/green.png"
var lights =[red,yellow,green];
var currentColor = 0;
function changeColor() {
var img = document.getElementById("light");
img.src= lights[currentColor];
if (currentColor === (lights.length - 1)) {
currentColor = 0;
} else {
currentColor++;
}
return false;
}
</script>
</head>
<body>
<button id="sequence" onclick="changeColor();">sequence</button>
<br><br><br>
<img id="light" src="https://s29.postimg.org/5ljr1ha3r/green.png" />
</body>
</html>
There are several ways you could handle it, but here's an easy one:
above:
function changered()
add this:
var cur_button = 1
Then change your button to this:
<button id="sequence" onclick="handle_click()">sequence</button>
and add this function:
function handle_click()
{
if(cur_button == 1)
{
cur_button = 2
changered()
}
else if(cur_button == 2)
{
cur_button = 3
changeyellow()
}
else if(cur_button == 3)
{
cur_button = 1
changegreen()
}
}
There you go
<input type="button" name="btnn" onclick="runFunction()" />
<script>
var red = "https://s23.postimg.org/bo5a8hzsr/red_jpg.png";
var yellow = "https://s24.postimg.org/dodxgn305/yellow.png";
var green = "https://s29.postimg.org/5ljr1ha3r/green.png";
var lights =[red,yellow,green];
var a =1;
function changered()
{
var img = document.getElementById("light");
img.src= lights[0];
return false;
}
function changeyellow()
{
var img = document.getElementById("light");
img.src= lights[1];
return false;
}
function changegreen()
{
var img = document.getElementById("light");
img.src= lights[2];
return false;
}
function runFunction()
{
if(a==1)
{
changered();
a++;
}
if(a==2)
{
changeyellow();
a++;
}
if(a==3)
{
changegreen();
a=1;
}
}
I can use the switch statement, and simply reference the lights array to determine which to display next. Seems pretty painless.
var red = "https://snowmonkey.000webhostapp.com/images/red.png"
var yellow = "https://snowmonkey.000webhostapp.com/images/yellow.png"
var green = "https://snowmonkey.000webhostapp.com/images/green.png"
var lights =[red,yellow,green]
handleClick = function(){
var light = document.getElementById("light");
switch (light.src) {
case lights[0]:
light.src = lights[1];
break;
case lights[1]:
light.src = lights[2];
break;
case lights[2]:
light.src = lights[0];
break;
}
}
#light {
float: right;
width: 50px;
}
<button id="sequence" onclick="handleClick();">sequence</button>
<br><br><br>
<img id="light" src="https://snowmonkey.000webhostapp.com/images/green.png" />
https://jsfiddle.net/x1rqwzvy/1/
You shouldn't add more than one onclick in your html code. If you do the handlers will activate simultaneously. This means you have to handle the change with JavaScript.
To determine the light you would simply increment a value in the following example:
function lightChange() {
lightChange.incrementer = lightChange.incrementer || 1;
switch (lightChange.incrementer) {
case 1:
changered();
break;
case 2:
changeyellow();
break;
case 3:
changegreen();
lightChange.incrementer = 0;
break;
}
lightChange.incrementer++;
function changered() {
var img = document.getElementById("light");
img.src = lights[0];
return false;
}
function changeyellow() {
var img = document.getElementById("light");
img.src = lights[1];
return false;
}
function changegreen() {
var img = document.getElementById("light");
img.src = lights[2];
return false;
}
}
then just change the onclick handler to lightChange instead of trying to add three consecutive handlers.
<button id="sequence" onclick="lightChange()">sequence</button>
how about
var counter = 0;
function changeColor(){
counter++;
var img = document.getElementById("light");
img.src= lights[counter % 3];
return false;
}
and your html should be:
<button id="sequence" onclick="changeColor()">sequence</button>
You can create a function array and then remove entries from it once done.
var functionArray = [changered,changeyellow,changegreen]
function sequenceClick(){
functionArray[0]();
functionArray.shift();
}
Complete Code:
var red = "https://s23.postimg.org/bo5a8hzsr/red_jpg.png"
var yellow = "https://s24.postimg.org/dodxgn305/yellow.png"
var green = "https://s29.postimg.org/5ljr1ha3r/green.png"
var lights =[red,yellow,green]
function changered()
{
var img = document.getElementById("light");
img.src= lights[0];
return false;
}
function changeyellow()
{
var img = document.getElementById("light");
img.src= lights[1];
return false;
}
function changegreen()
{
var img = document.getElementById("light");
img.src= lights[2];
return false;
}
var functionArray = [changered,changeyellow,changegreen]
function sequenceClick(){
functionArray[0]();
functionArray.shift();
}
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<button id="sequence" onclick="sequenceClick()">sequence</button>
<br><br><br>
<img id="light" src="https://s29.postimg.org/5ljr1ha3r/green.png" />
</body>
</html>

Problem with putting in the right parameters

I have problem with putting in the right parameters from an eventListener into a function.
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript">
window.onload = function() {
var galleryContainer = document.getElementById('galleryContainer');
var image = galleryContainer.getElementsByTagName('div');
//console.log(image);
var images = new Array();
images.push(image);
for(var i = 0; i < images[0].length; i++) {
images[0][i].addEventListener('click', function() {showImage(this)
}, false);
};
}
// I dont know with parameter to put into showImage() from the listener.
function showImage( here is the problem ) {
var preview = document.getElementById('preview');
preview.innerhtml = image.innerhtml;
// I want to put the image into the preview element.
}
</script>
</head>
<body>
<div id="galleryContainer">
<div>trams</div>
<div>trams</div>
<div>trams</div>
<div>trams</div>
</div>
<div id="preview" style="width: 200px; height: 200px; border: 1px solid red"></div>
</body>
Try this code:
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript">
window.onload = function() {
var galleryContainer = document.getElementById('galleryContainer');
var images = galleryContainer.getElementsByTagName('div');
//console.log(images);
for(var i = 0; i < images.length; i++) {
images[i].addEventListener('click', showImage, false);
};
}
// I dont know with parameter to put into showImage() from the listener.
function showImage(ev) {
ev=ev||event; // ev now point to click event object
var preview = document.getElementById('preview');
preview.innerHTML = this.innerHTML; // this point to DIV(trams)
}
</script>
</head>
<body>
<div id="galleryContainer">
<div>trams1</div>
<div>trams2</div>
<div>trams3</div>
<div>trams4</div>
</div>
<div id="preview" style="width: 200px; height: 200px; border: 1px solid red"></div>
</body>
Working example http://jsfiddle.net/Cp6HJ/
window.onload = function() {
var galleryContainer = document.getElementById('galleryContainer');
var image = galleryContainer.getElementsByTagName('div');
//console.log(image);
var images = new Array();
images.push(image);
for(var i = 0; i < images[0].length; i++) {
var callback = function(item){ return function(){ showImage(item); }; }(images[0][i]);
images[0][i].addEventListener('click', callback, false);
};
};
function showImage( item ) {
var preview = document.getElementById('preview');
preview.innerHTML = item.innerHTML;
}
Use this for the function definition statement :
function showImage(image) {
...
}
And correction in the inner html statement:
(note the capitalized 'H')
preview.innerHTML = image.innerHTML;

Categories