FOR cycle just including closure still displays only the last picture - javascript

Good evening,
I have many articles on my web (my own do-it-yourself manuals how to create...) interspersed with pictures (it is written in Czech language). These pictures are small and I want using onclick in html to display them bigger always close to those small. I.e. each bigger picture is to be displayed beside his small one. This is a practical illustration:
http://mix.zlatberry.cz/obrazky1.html (clicking on the big picture - unintentionally at the end of site - it is shut down).
But, clicking any small picture only the last big picture is displayed!
Currently I know that only so called closure is remedy for my problem but despite this trick I am not able to force my iteration to show the first big picture beside the first small one, the second big picture beside the second small one and so on and so on.
HTML (is not from my head). Btw, please, is it posible to write this code - small picture versus big picture - easier way??
let obr = new Array('velka-fotka1', 'velka-fotka2', 'velka-fotka3', 'velka-fotka4', 'velka-fotka5');
for (let i = 0; i < obr.length; i++) {
(function() {
let x = i;
let fotka = document.getElementById(obr[x]);
function ZobrazFotku() {
fotka.style.display = 'block';
}
document.write(x); //document.write(x) writes numbers 01234
function SchovatFotku(div) {
document.getElementById(div).style.display = 'none';
}
})();
}
<div id='velka-fotka1'>
<div class="foto">
<a href='#' onclick="SchovatFotku('velka-fotka1'); return false" title='Shut down'></a>
<img src='bigmotopelech1.jpg' alt='click for display small picture' onclick="SchovatFotku('velka-fotka1'); return false" />
</div>
</div>
<div class="foto">
<a onclick="ZobrazFotku('bigmotopelech1.jpg'); return false" href='bigmotopelech1.jpg' title='display the big picture'><img src='motopelech1.jpg' width="320" height="240" alt="Pneumatika z motorky a deka"></a>
</div>
Testing my closure I tried to add document.write(x) but numbers are listed TOGETHER, not one after another by clicking small pictures, and all big pictures are displayed, to make thing worse, in a separate window of browser:
http://mix.zlatberry.cz/obrazky2.html
So I am really at the end of my tether :-( . I try to solve it since September.
I will be very appreciative for help leading to solving my problem. I enjoy to modify all my websites this way and I am in the doldrums...
Many thanks in advance <3
HTML:
<div id='big-photo1'>
<div class="foto">
<a href='#' onclick="HidePhoto('big-photo1'); return false" title='Hide'></a>
<img src='bigmotopelech1.jpg' alt='click for display a small photo' onclick="HidePhoto('big-photo1'); return false" />
</div>
</div>
<div class="foto">
<a onclick="DisplayPhoto('bigmotopelech1.jpg'); return false" href='bigmotopelech1.jpg' title='display a big photo'><img src='motopelech1.jpg' width="320" height="240" alt="Pneumatika z motorky a deka"></a>
</div>
Javascript:
let picture = new Array('big-photo1', 'big-photo2', 'big-photo3', 'big-photo4', 'big-photo5');
for (let i = 0; i < picture.length; i++) {
(function() {
let x = i;
let photo = document.getElementById(picture[x]);
function DisplayPhoto() {
photo.style.display = 'block';
}
function HidePhoto(div){
document.getElementById(div).style.display='none';
}
})();
}
Here is link with English variables etc. http://mix.zlatberry.cz/pict1.html

Change your ZobrazFotku function to accept the id of the div in which the img is contained as the first argument. This way you don't need the for loop at all.
function ZobrazFotku(id) {
var div = document.getElementById(id);
div.style.display = 'block';
}
function SchovatFotku(div) {
document.getElementById(div).style.display = 'none';
}
JSFiddle Demo: http://jsfiddle.net/rkaqzx2v/

Related

How to check if an image is clicked in a function with JavaScript?

I hope this is the right place to ask, I am new to html and javascript. I want to make a simple "game". The part where I got stuck is that everytime you click on any image in the different html screens the function set to that image will be executed. It has no order to it. For example you can press an image that is supposed to be at the end of the game even if you just started it. I think I know where the problem is but not sure how to fix it.
I believe it has something to do with this part of my html code: `
<img id="img1" src="map.jpeg" onclick="myFunction()"/>
Which means that everytime you click the image the function "myFunction()" will be executed.
This is the myFunction code, that shows a "you have found the map" box and then shows an image that has display:"none" in a html file :
var r = confirm("You have found the map!");
if (r == true) {
document.getElementById("img2").style.display = "inline";
} else {
}
}
I think the solution to my problem would maybe be to have the onclick="myFunction()" part in the javascript function somehow, that first checks if the image has been clicked (once) and then continuing with the condition I set. Is there any way to do that? Thankful for any help!
You can count the number of clicks in your function and base your logic on the number of clicks.
I've attempted to use some of the code you provided in my answer below. Please run the snippet and look at the notes in the javascript to understand what's happening.
// set clicks variable to 0, we will use this var to count the number of clicks on the image
var clicks = 0;
// declare function to handle clicks
function handleClicks() {
//whenever this function runs, it will increase the clicks count by 1
clicks += 1;
document.getElementById("clicks").innerHTML = clicks;
// if number of clicks is greater than one then show image 2
if (clicks > 1) {
console.log('this image has already been clicked ' + clicks + ' times.')
document.getElementById("img2").style.display = "inline";
} else {
// if clicks aren't greater than 1 do something else
console.log('this is the first time you clicked this image.')
}
}
<div>
<img id="img1" style="width: 25%;" src="https://cdn.pixabay.com/photo/2022/10/03/23/41/house-7497001_960_720.png" onclick="handleClicks()" />
<img id="img2" style="display:none; width: 25%" src="https://cdn.pixabay.com/photo/2022/09/25/23/28/android-7479380_960_720.png" onclick="onClick()" />
<br/>
<p id="clicks"></p>
</div>

Trying to get alt text to show when a user clicks on an image

There's probably something very important I'm missing here, but I've been working on this code and I keep getting stuck with the same errors over and over again--I'm not sure what I'm doing wrong.
Here is my HTML
<html lang="en">
<head>
<meta charset="utf-8">
<title>Images to Text</title>
<link rel="stylesheet" href="styles.css" type="text/css"/>
</head>
<body>
<h1>Some of my Favorite Animals.</h1>
<h2>Capybara & Mantis Shrimp</h2>
<div id='showAlt'>
<img src="capybaraman.jpg" height="190" alt="A picture of a capybara in the arms of a man, showing that they are about the size of dogs but look comparable to guinea pigs.">
<img src="capybaramonkey.jpg" width="300" alt="A picture of a capybara with monkeys petting and on top of the capybara.">
<img src="capybarabird.png" width="300" alt="A picture of a capybara laying in the mud. There is also a bird sitting on top of them.">
<img src="mantisshrimp.jpg" width="300" alt="A picture of a mantis shrimp with its' arms open, they are rainbow with large eyes. They have small wing-like structures coming from the sides of their bodies.">
<img src="mantisbody.jpg" width="230" alt="A picture showing the mantis shrimp's body, it is long and looks like a lobster's tail with the same texture.">
<img src="mantisclose.jpg" width="300" alt="A picture close up to a mantis shrimp's face, you can see their large eyes and their 'mouth'.">
</div>
<div id="clickToShow"></div>
<script src="imagetotext.js"></script>
</body>
</html>
Here is my JavaScript
let altText = document.getElementById('clickToShow');
let clicker = document.getElementById('showAlt');
for (let x = 0; x < document.images.length; x++) {
altText[x].addEventListener('click', imageToText);
}
function imageToText() {
let clickImage = this.alt;
clicker.textContent = clickImage;
}
I was trying to add a for loop each time the user clicked the image, it shows its alt text but I keep getting errors saying that it cannot read property addEventListener of undefined imageToText.
I thought it would be that the JS was too high up in the HTML since it is undefined, but even after moving my script tag down this is still happening.
I also want to use the event listener tag--I haven't learned jQuery yet.
Any help would be great! I'm feeling stuck with my code at the moment.
I was trying to add a for loop each time the user clicked the image
Then add the event listener to each image - you're currently trying to add click listeners to altText[x], but altText is a single element, a <div> - it's not a collection.
You also probably don't want to clear the #showAlt div containing the images, since then they'll all disappear - did you want to add it to the other div?
for (const img of document.querySelectorAll('img')) {
img.addEventListener('click', imageToText);
}
function imageToText() {
altText.textContent = this.alt;
}
here is the error
for (let x = 0; x < document.images.length; x++) {
altText[x].addEventListener('click', imageToText);
}
you get altText from document.getElementById('clickToShow'); right?
inside , no array, that is why addEventListener couldn't read it
change it to:
for (let x = 0; x < document.images.length; x++) {
clicker[x].addEventListener('click', imageToText);
}
and chang this to
function imageToText() {
let clickImage = this.alt;
altText.textContent = clickImage;
}

Why are the images not coming up for document.createElement

I am a very novice coder and I am creating a game that calculates the area of a given rectangle however once the page loads, the image does not show and thus the user cannot answer the question.
An example image has been copied below
The "score" does not display either. Any help would be greatly appreciated :)
var number1;
var number2;
var response;
var calcanswer;
var score = 0;
window.onload = areaquestion1;
myScore.text = "SCORE: " + score;
function areaquestion1() {
var question = document.createElement("question");
question.setAttribute("src", "Images/2*1.png");
question.setAttribute("width", "304");
question.setAttribute("height", "228");
question.setAttribute("alt", "2*1");
document.body.appendChild(question);
var number1 = 2
var number2 = 1
calcanswer = (number1*number2);
var question = document.getElementById("question");
question.innerHTML = "What is the area of this lego brick?";
check();
areaquestion2();
}
function areaquestion2() {
var question = document.createElement("question");
question.setAttribute("src", "Images/3*2.png");
question.setAttribute("width", "304");
question.setAttribute("height", "228");
question.setAttribute("alt", "3*2");
document.body.appendChild(question);
var number1 = 3
var number2 = 2
calcanswer = (number1*number2);
var question = document.getElementById("question");
question.innerHTML = "What is the area of this lego brick?";
check();
areaquestion3();
}
function check()
{
var statusDiv = document.getElementById("status");
response=document.getElementById("answer").value;
if(response != calcanswer)
statusDiv.innerHTML="Incorrect";
else
if (response==calcanswer)
{
statusDiv.innerHTML="Very good!";
score ++;
document.getElementById("score").textContent = score
document.getElementById("answer").value = "";
problem();
}
}
<!DOCTYPE html>
<html>
<title>Lego Area</title>
<head>
<link rel="stylesheet" href="CSS/Play.css">
<script src="JavaScript/Play.js"></script>
</head>
<body onload="areaquestion1();">
<div class="header">
<h1>LEGO AREA</h1>
<p>Calculating <b>area</b> with Emmet.</p>
<div id="score" class="score" value="SCORE:"></div>
</div>
<form>
<div class="row">
<div class="side">
<div id="question"></div>
<div id ="prompt"></div>
<input type="text" id="answer"/>
</div>
<div class="main">
<input id="solve" type="button" value="CHECK!" onclick="check()" />
</div>
</div>
</form>
<div id="status"></div>
<!-- Footer -->
<div class="footer">
<div class="practice"> <img src="Images/legoBlue2.png" id="practicebtn" width="20%"></div>
<div class="play"> <img src="Images/legored2.png" id="playbtn" width="20%"></div>
</div>
</body>
</html>
This is my first question I'm attempting to answer -- so pretty big deal. Anyway...
A few things I noticed:
I got pretty confused reading the code seeing the question variable being used so much for different parts of the code. So I changed the var question to var imageBlock to make it more readable for me.
You were running the areaquestion1() function onload. Since the check() function was run as a part of the areaquestion1() function it was being run as well, in-turn displaying 'Incorrect' even before an answer was entered. I changed this to document.getElementById("solve").check(); to ensure it runs only after the CHECK! button was clicked.
Finally getting to your actual question. It looks like you are trying to use document.createElement to create an image with an id of question, however based on geeks for geeks and W3 Schools you use the document.createElement to create the img element. THEN you can set the id attribute to whatever you like. In this case, I switched it to imageBlock.setAttribute("id", "madeUpImg"); to help with my readability.
So this is what I did, I think there are a lot of improvements you can make, but this works and it will give you a good start:
function areaquestion1() {
var imageBlock = document.createElement("IMG");
imageBlock.setAttribute("id", "madeUpImg");
imageBlock.setAttribute("src", "guWFE.png");
imageBlock.setAttribute("width", "304");
imageBlock.setAttribute("height", "228");
imageBlock.setAttribute("alt", "2*1");
document.body.appendChild(imageBlock); // this appends it to the bottom of the page
number1 = 2
number2 = 1
calcanswer = (number1*number2);
var question = document.getElementById("question");
question.innerHTML = "What is the area of this lego brick?";
document.getElementById("solve").check();
// areaquestion2(); }
All of this is edited to address your further questions:
For appending it in the appropriate spot: I haven't had time to jump back in my code, but this is what I'm thinking. Currently, when you read your code you have document.body.appendChild(question); This JavaScript is telling the computer to find the document, then find the body of that document, then run the appendChild function. So, basically it is saying - "computer, append the question variable to the body of the document". So, what's wrong with this? Well, you want to append it to a specific div! So, you're extremely close, but you're not grabbing the question div! You need to use code to tell the computer to find the question div, then append the image to that div. I'd do something like this: document.getElementById('question').appendChild(imageBlock) this now means the code is grabbing onto the div that you want to append it to then, appending the imageBlock to that div.
I commented out that areaquestion2 because I know you're going to run into more problems. 1. If you call the areaquestion2in the areaquestion1 function it will run immediately when the website loads (you're calling the area question1 on load). I think this is going to make both images appear at the same time. Why? It is just being instructed to append another image to the question div. 2. You probably don't want both images appearing at the same time. So, you're going to need to find a way to replace the first image rather then trying to add another one.
That's about all I can help you with on this for now. I think that if you continue to work through this then refactor it, you're going to learn a ton. I think you should try to bring this to one function by assigning questions to variables, then passing those variables in as arguments to your function. If you haven't already, I'd highly recommend going through FreeCodeCamp's stuff lesson by lesson.
Hope this helped!!

JavaScript, image changing program not functioning

So I'm new to coding, so thought that I would give some more simple things a go. I tried to make a code which would change an image every time a button is pressed, but it does not function. For a while I had it functioning so that the square would display but the image would not change when the button is pressed. But I then altered it and it will now not run with internet explorer due to a syntax error. Any help would be seriously appreciated, please bare in mind that it could be completely wrong, as I just used guides off of the internet :) I also probably inserted this code wrong, but I tried ;)
<!DOCTYPE html>
<html>
<body>
<img id="shape" src="square.gif">
<button type="button" onclick="changeImage()">Change Image/button>
<script>
var list = [
"red.gif",
"square.gif"
];
var index = 0;
function changeImage() {
index = index + 1;
if (index == list.length) index = 0;
var image = document.getElementById('shape');
image.src=list[index];
}
</script>
I did find two things that will help your code work better:
I fixed your closing button tag
I iterated your index variable after the if statement and image replacement. That way your first click didn't use the same image.
This tested fine in IE with no errors.
See my code below.
var list = [
"http://placekitten.com.s3.amazonaws.com/homepage-samples/96/140.jpg",
"http://placekitten.com.s3.amazonaws.com/homepage-samples/96/139.jpg"
];
var index = 0;
function changeImage() {
var image = document.getElementById('shape');
if (index == list.length) index = 0;
image.src=list[index];
index = index + 1;
}
<img id="shape" src="http://placekitten.com.s3.amazonaws.com/homepage-samples/96/139.jpg" />
<button type="button" onclick="changeImage()">Change Image</button>

how to make the following code faster?

I am developing a application with phonegap. on my pc everything runs fine but on my mobile device its just too slow.
i think the problem is on the show function, the android browser seems to needs really long to hide and show elements
what can be improved?
function show(id){
$('.view').hide()
//alert('show ' + id)
$('#'+id+'View').show()
scroll(0,0)
}
function getSoundHTML(id, myname, del){
if (del != true){
var imgsrc = 'plus.png'
var f = function(){
addToCostumSounds(id)
alert('added to favorites')
}
}else{
var imgsrc = 'minus.png'
var f = function(){
removeFromCostumSounds(id);
$(this).fadeOut().next('div').fadeOut();
}
}
var div = $('<div></div>').addClass('box').html(myname).css('border-color', '999999').click(function(){
play(id)
})
var img = $('<img></img>').attr('src', imgsrc).addClass('sideimg').click(f)
return $('<div></div>').append(img).append(div)
}
for(var category in categories){
var f = function(category){
$('#'+category+'Btn').click(function(){
show(category)
var categoryView = $('#'+category+'View')
for(var key in categories[category]){
var div = getSoundHTML(key, categories[category][key])
categoryView.prepend(div)
}
var img = '<img src="menu.png" class="menuimg"/>'
categoryView.prepend(img)
categoryView.append(img)
})
}
f(category)
}
the html:
<div class="btn" id="noBtn">no _</div>
<div class="btn" id="thatIsBtn">that is _</div>
<div class="btn" id="thereIsBtn">there is _</div>
<div class="btn" id="thisIsBtn">this is _</div>
...
<div class="view" id="noView"></div>
<div class="view" id="thatIsView"></div>
<div class="view" id="thereIsView"></div>
<div class="view" id="thisIsView"></div>
...
Whilst it may not have an effect on Desktops, your massive lack of semi-colons in the right places may have an effect on mobile devices.
The JavaScript engine has to run through and try to work out where the semi-colons need to go. See this transcript from the ECMAScript specification.
To be honest I think thats only a few milliseconds of time-saved, but its a starting point for now - and good practice for the future.
Here's your problem:
for(var category in categories){
var f = function(category){
...
for(var key in categories[category])
...
}
f(category)
}
You have two BIG issues here:
You're defining a function within a loop. While this is sometimes needed, you should do your very best to avoid defining things within a loop unless you absolutely need to. In this case, you could probably move the f function out of the loop entirely without breaking your code.
Nested loops. You have a for ... in within a for ... in loop. This is largely due to the first problem I pointed out, but in general nested loops are a big no-no from a performance standpoint.
ok, i think i got the only way to improve the peroformance:
if someone clicks on a button (class="btn") he is redirected to a new fresh page that has the entire page in HTML and does not build it with javascript.

Categories