How to switch between different HTML elements with the same onclick function? - javascript

Right now i have four images which are being dynamically presented on html. This is done via an onload function. Basically when i click on of those wheels I would like the image to change for around one second then go back. But right now only one wheel changes colour which is quite annoying.
function setWheels() {
document.querySelector(".blue-wheel").innerHTML = "<img src='blue-dark.svg.svg' onclick='buttonEvent()'>";
document.querySelector(".red-wheel").innerHTML = "<img src='red-dark.svg.svg' onclick='buttonEvent()'>";
document.querySelector(".green-wheel").innerHTML = "<img src='green-dark.svg.svg'>";
document.querySelector(".yellow-wheel").innerHTML = "<img src='yellow-dark.svg.svg'>";
}
function buttonEvent() {
if (document.querySelector(".blue-wheel")) {
document.querySelector(".blue-wheel").innerHTML = "<img src='blue-light.svg.svg'>";
setTimeout(setWheels, 800);
}
else if (document.querySelector(".red-wheel")) {
document.querySelector(".red-wheel").innerHTML =<img src='red-light.svg.svg'>";
setTimeout(setWheels, 800);
}
}
I havnt added the other coloured wheels as i do predict that they will have the same effect. I do believe that the setTimeout may be one of the problems as I'm calling the setWheels function but the first if statement seems to be the only one that changes colour even when i click the other div.

Your if statements aren't checking anything useful. if(document.querySelector(".blue-wheel")) is only checking if that element is there, not if the image inside was clicked.
If you want to know which image was clicked, pass it in as a parameter to the function.
<img src='blue-dark.svg.svg' onclick='buttonEvent(this)'>
and in your javascript, just change the src for the image that was clicked and then set a timeout to change it back.
function buttonEvent(e) {
e.src = e.src.replace('dark', 'light');
setTimeout(() => {e.src = e.src.replace('light', 'dark')}, 800);
}
if you want to protect against fast clicking while the image is already highlighted (improve performance) you can add a return:
function buttonEvent(e) {
if (!e.src.includes('dark')) return;
e.src = e.src.replace('dark', 'light');
setTimeout(() => {e.src = e.src.replace('light', 'dark')}, 800);
}

You are missing a "
.innerHTML =<img src='red-light.svg.svg'>";
should be
.innerHTML = "<img src='red-light.svg.svg'>";

you can use a variable (let x=0) to count on what image are you on. then make function that will see what x = 0 so it will show the first image then add one to the x (like "x++")but before you show the image you need to remove the last one, so then you need to loop through the images (you can give the same class to the images) like ".forEach()" and in that function you can see if that image is on the page or is shown to the user then just remove it, then x =1 in that case just show the second image and so on. you can add "if" statement that will check "if x>=(image count)" when that happens then just "x=0" and it will reset

Related

Button stops working when elements are placed after it (javascript)

I'm trying to make a text based idle game where multiple buttons are involved, and text around those.
Whenever I try to put text after the "Work" button it stops working, stops calling the callback on click.
I tried putting the text in a separate div, which didn't work, I also tried putting the button in its own div, which made things worse. The last thing I tried was putting the text written by the write functions (which made the formatting terrible) in a paragraph tag which somehow also didn't work.
I don't know what else to try. The only thing that doesn't seem to break it so far is putting other buttons after it.
I'm using a function to create buttons called createButton(), it takes in 3 arguments, the button text, the button ID, and the button callback, and to draw text I'm using a "custom" write function (details at bottom).
For the work button I'm passing in the work() function as the callback.
createButton function:
function createButton(text, id, callback){
// console.log(text + " " + id + " " + callback)
var button = document.createElement("button");
button.innerHTML = text; //create a button element
//var body = document.getElementsByTagName("body")[0];
gameDiv.appendChild(button); //set its parent to the game div
button.addEventListener ("click", callback); //add the callback as a listener
}
work function:
function work(){
money++;
//TODO: find better way of updating money counter
draw(); //redraw to update money counter
if(stage == 1){ //increment the current stage if needed (for pacing)
stage = 2;
setTimeout(function(){
buttonStage = 1;
createButton("Buy Box", "buyBox", buyBox);
}, 1000);
}
}
draw function:
function draw(){
clear(); //clear the screen
for(var i=0;i<stage;i++){
switch(i){
case 0:
writeln("Do this");
writeln(" ​|");
writeln(" |");
writeln("▼");
createButton("Work", "work", work); //recreating a button every second might be a problem, but i dont know how to get it to position properly otherwise
break;
case 1:
write("<div id=\"stage2\">");
writelnDiv("<br><br>Money: " + Math.round((money*100)/100), "stage2");
writelnDiv("", "stage2");
writelnDiv("Now do this", "stage2");
writelnDiv(" ​|", "stage2");
writelnDiv(" |", "stage2");
writelnDiv("▼", "stage2");
write("</div>")
if(buttonStage > 0){
createButton("Buy Box", "buyBox", buyBox);
}
break;
}
}
}
The write, writeDiv, writeln, and writelnDiv functions both just add the text to the div's innerHTML.
All code is here: https://js.do/Grimtin10/637778
The solution is probably simple, but I don't exactly know what I'm doing with javascript.
If any more info is needed to solve this I can provide it.
Alright, I figured out a solution.
Instead of using document.createElement I just created the button using HTML tags directly appending it to the div.
It's kind of an awful way of doing it, but it works.

Refresh Page with JavaScript OnClick

Within my pen, I'd like to refresh my page after each click of a door. Not sure where I should drop the window.location.reload();
Here's the pen
https://codepen.io/tacodestroyer/pen/bROpeQ
function openDoor(field) {
var y = $(field).find(".thumb");
var x = y.attr("class");
if (y.hasClass("thumbOpened")) {
y.removeClass("thumbOpened");
}
else {
$(".thumb").removeClass("thumbOpened");
y.addClass("thumbOpened");
}
}
Thanks!
If you're wanting to put random images behind the door, the easiest way would be to create a series of CSS classes for divs that have background images then keep those classnames within an array in your JS. Then when you click on a door, you randomly choose one of the items in that array and apply that class the way you're applying the "open door" effect.
I suppose you want the opening-door animation to complete before reloading the page. You could use the transitionend event for that:
function openDoor(field) {
var y = $(field).find(".thumb");
var x = y.attr("class");
if (y.hasClass("thumbOpened")) {
// NB: This might never happen given that you reload the page once you open a door
y.removeClass("thumbOpened");
}
else {
$(".thumb").removeClass("thumbOpened");
y.addClass("thumbOpened");
// Wait for the animation to end:
$(".thumb").on("transitionend", function() {
// ... and then reload, or do whatever else you want to happen next
window.location.reload();
});
}
}

Button toggle to switch between images nd the text display on it/ raphael js/ javascript / html

In my current assignment I got:
Create a toggle button on the html page that visually indicates what state it is in by changing the text displayed on it (e.g. changes between “up” and “down”, or “smiling” and “not smiling”) and by switching between two images, as well.
a. Hint: you will have to use a “state” variable outside the button’s listener callback function to re- member the button’s state between event callbacks.
4. Use the toggle button to toggle the mouth between a smile and a frown. In your button ‘click’ listener, check the button’s state with an ‘if’ statement to control whether you are going to make a smile or a frown.
I am quite confused as I searched in web - there are so many ways to create a button, in Html or in css.
Can somebody post a similar example please ?
Use the element.click and provide a callback click function. In this case the callback is the update function.
In the update function, check for the current src, i.e. the source for the image element. Update the src of the image and the text of the button accordingly.
I have also made it interactable in the image part. If not required just remove this line
imageElem.click(update);
var imageElem = document.getElementById('test_Img'),
buttonElem = document.getElementById('test_Btn'),
img1 = 'http://www.fantazia.org.uk/images/600px-Smiley_svg_small.png',
img2 = 'http://www.clipartsgram.com/image/2060213170-sad-smiley-face-clipart-mclpbaqca.png';
imageElem.addEventListener("click", update);
buttonElem.addEventListener("click", update);
function update() {
var src, text;
if (imageElem.src === img1) {
src = img2;
text = 'Sad';
} else {
src = img1;
text = 'Smile';
}
buttonElem.value = text;
imageElem.src = src;
}
<input type = 'button' id="test_Btn" value = 'Smile'/>
<img id="test_Img" src='http://www.fantazia.org.uk/images/600px-Smiley_svg_small.png' />

Nested function and else condition not working

I am practicing JS doing a project and have run into issues (again).
Just upfront, to explain what i want.
I have the top level buttons with nation names, on click a pic will fade into a container just for that. It gets the pic from the first array on line 1.This all works very well. However...
When that container is visible, I want a click handler on the "next" button to the right. This handler is one function (line 29-42) which animates the second div(.containsNext) by changing opacity and rotate values.
This function also calls another function (next, this should change the target div background with pics from the new Array) and has an if else statement.
The if condition works as it is supposed to.
The else condition does not run, even if i take out the nested next() function.
I think the error (console doesn't return one) on the next function is the lines 15 and 16, I know those lines look "funny":-)
And the if statement in the wrapper function does not work either.
How to fix this? Please make sure to select France, Italy or Croatia buttons, or the next button will not respond at all (do not know why either).
One more question on the side, what would be an economical way to store the pics for all the nations arrays selected/triggered by the next button?
Also how to do implement the proper nations array to be selected based on the top button nation selection?
Thank you guys
function
var imgLenght = 3;
var currentImg = 1;
function next() {
var imgContainer = document.querySelector(".containsNext");
if(currentImg > 0)
{
imgContainer.style.background = "url(" + "im[currentImg-1]" + ")";
currentImg = currentImg - 1;
}
}
Link to the pen:
http://codepen.io/damianocel/pen/gPggLB
use correctly nested quotes:
imgContainer.style.background = 'url("' + im[currentImg-1] + '")';

setTimeout not working with onmouseout

First, here are the problematic lines of code:
<a onmouseover="hoverDisplay(this)" onmouseout="setTimeout(unHoverDisplay(), 3000);" href="http://rabbit.jpg">
Rabbit
</a><br>
Basically, I want the image to load and appear when I hover over the link, and I want the it to disappear after some time when I hover out of the link. The methods:
hoverDisplay(this)
unHoverDisplay()
display and remove the image, respectively, but when I tried to delay unHoverDisplay(), it didn't work; the image disappeared the moment my mouse hovered off the link.
I've tried adding and removing the semicolon after the setTimeout (not sure if the semicolon is necessary or not), and I tried delaying the hoverDisplay function as well, which did not work. Aside from the delay problem, the two functions work as intended.
This seems like a simple issue, but I can't figure out what I'm doing wrong. Help is appreciated. Thanks.
Not sure if this is necessary, but here are the implementations of the two functions:
//Display image for link that you hover over
var address; //Address of image
var toBeDisplayed; //Declaring img object
var maxHeight=screen.height;
var maxWidth=screen.width;
var invisible=document.getElementById("invisible"); //the div in which the image is contained
function hoverDisplay(imageLink)
{
address=imageLink.getAttribute("href"); //get address
toBeDisplayed=document.createElement("img"); //create img
toBeDisplayed.setAttribute("src", address); //give img the address
//Resize img if it doesnt fit on the screen
if(toBeDisplayed.height > maxHeight)
{
toBeDisplayed.style.height="" + maxHeight + "px";
}
else if(toBeDisplayed.width > maxWidth)
{
toBeDisplayed.style.width="" + maxWidth + "px";
}
invisible.appendChild(toBeDisplayed); //display image by adding it as a child to a div
invisible.style.visibility="visible"; //make div visible
toBeDisplayed.style.border="solid yellow 5px";
}
//Remove image once you hover out of the link
function unHoverDisplay()
{
//Removes all children of the div
while(invisible.firstChild)
{
invisible.removeChild(invisible.firstChild); //remove img by removing it as a child
}
invisible.style.visibility="hidden";
}
The trouble is that the parentheses after unHoverDisplay in your first argument to setTimeout are causing unHoverDisplay to be executed immediately. You simply want to pass the function by its identifier without the parentheses:
onmouseout="setTimeout(unHoverDisplay, 3000);"
You are passing a function as a parameter to setTimeout, not invoking it. Hence, you don't need those parentheses along with the function name, all that is required is the function name itself.
onmouseout = "setTimeout(unHoverDisplay, 3000);"

Categories