Button onclick doesn't respond - javascript

I am fairly new to JavaScript and I am trying to make my own image gallery as my first simple project. I expected it to go smoothly, but it seems like I am doing some trivial mistake, and I have no idea where.
So, my initial plan was: I would set up an image element with empty src property, create an array of image names, add a function that will increase the array pointer by 1 any time it is triggered, and then just add the corresponding value in the array to the src.
It doesn't work, though. Could you please try to see any errors in the code? I really have no idea what to do, just can't find a mistake.
<html>
<body>
<img src="" id="imageCanvas">
<div id="counterDisplay"></div>
<script type="text/javascript">
var images = ["increased.jpg","knight.jpg","knight-g.jpg","golden.jpg","land.jpg"];
var counterDisplay = document.getElementById("counterDisplay");
var imageCanvas = document.getElementById("imageCanvas");
var imageCount = 0;
// function intended to increase the array position indicator by 1, but it always only increases it in relation to the original imageCount value (0), how to make it save the already increased value?
function changeCount() {
imageCount = imageCount+1;
}
counterDisplay.innerHTML = imageCount;
imageCanvas.setAttribute("src",images[imageCount]);
</script>
// The main problem: it just refuses to respond!
<button onclick="changeCount()">NEXT</button>
</body>
</html>

I didn't debug through this, but my guess is that onclick is being called, but you are not updating the count in that changeCount code.
Try putting almost all the code in changeCount.
function changeCount() {
imageCount = imageCount+1;
counterDisplay.innerHTML = imageCount;
imageCanvas.setAttribute("src",images[imageCount]);
}

This function runs when the the button is clicked.
function changeCount() {
imageCount = imageCount+1;
}
This code is run when the script first loads.
counterDisplay.innerHTML = imageCount;
imageCanvas.setAttribute("src",images[imageCount]);
You want it to run when the button is clicked. Move it inside the function.

Related

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

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

JavaScript - Modify function to be reusable in later instances?

This is a followup to this question.
I have a function that I would like to make reusable so I don't have to make new, very similar functions over and over to achieve the same effect. Specifically, I would like to know how to change var message after the first function instance runs without losing the original message.
Here's my code:
var message = `This message is (hopefully) a successful implementation of JS video game scrolling!
//Pretty cool, huh? Well, believe it or not, this whole page is a test for a very basic interactive story using HTML/JavaScript!
// Let's see if we can add some fade-in buttons, shall we?
//(By the way--you can click anywhere in this window to instantly clear through subsequent text scrolls.)`;
var timer = setInterval(dialogue, 20);
function dialogue(add = 1){ // By default 1 character is made visible
var len = $("#pid").text().length + add; // Get desired length
$("#pid").text(message.substr(0, len)); // Make the change
if (len < message.length) return; // Nothing more to do
clearInterval(timer); // All is shown, so stop the animation
$("#button1").fadeIn(); // and fade in the button
};
// On click, pass the length of the message to the function
$(document).click(dialogue.bind(null, message.length));
// Hide the button on page load
$("#button1").hide();
<!DOCTYPE HTML>
<html>
<head>
<title>Sandbox</title>
<link rel="stylesheet" href="mainstyle.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
</head>
<body>
<p id="pid"></p>
<button id="button1">Ooh, here's one! Click to see what it does!</button>
</body>
</html>
edit: https://jsfiddle.net/n8Lczdk0/4/
I'm not sure what you mean, but if you wrap everything in a function that takes message as an argument, then it'll be in the dialogue function's closure and you'll be able to update var message after you call the wrapper function without dialogue() knowing about it. As they say, a few lines of code are worth hundreds of prose:
var message = `This message is (hopefully) a successful implementation of JS video game scrolling!
Pretty cool, huh? Well, believe it or not, this whole page is a test for a very basic interactive story using HTML/JavaScript!
Let's see if we can add some fade-in buttons, shall we?
(By the way--you can click anywhere in this window to instantly clear through subsequent text scrolls.)`;
const f = message => {
var timer = setInterval(dialogue, 20);
function dialogue(add = 1){ // By default 1 character is made visible
var len = $("#pid").text().length + add; // Get desired length
$("#pid").text(message.substr(0, len)); // Make the change
if (len < message.length) return; // Nothing more to do
clearInterval(timer); // All is shown, so stop the animation
$("#button1").fadeIn(); // and fade in the button
};
// On click, pass the length of the message to the function
$(document).click(dialogue.bind(null, message.length));
// Hide the button on function call
$("#button1").hide();
}
f(message)
message = "some new value"
So above, I'm essentially wrapping your whole js code in a function that takes message as an argument. Kinda like currying your dialogue function.
You could also pass your ids as arguments and make it fully reusable. Just pass a message and DOM ids to the function and the magic unrolls with associated buttons fading in as various texts show up.
Hope this helped, cheers,
thomas
You can try with below one way
You can pass one optional argument(message) to the function and check if it is passed then use that message otherwise use default original message.
var message = `This message is (hopefully) a successful implementation of JS video game scrolling!
Pretty cool, huh? Well, believe it or not, this whole page is a test for a very basic interactive story using HTML/JavaScript!
Let's see if we can add some fade-in buttons, shall we?
(By the way--you can click anywhere in this window to instantly clear through subsequent text scrolls.)`;
var timer = setInterval(dialogue, 20);
function dialogue(add = 1, custom_message){ // By default 1 character is made visible
var temp_message;
if(typeof custom_message === "undefined") {
temp_message = message;
}
else {
temp_message = custom_message;
}
var len = $("#pid").text().length + add; // Get desired length
$("#pid").text(temp_message.substr(0, len)); // Make the change
if (len < temp_message.length) return; // Nothing more to do
clearInterval(timer); // All is shown, so stop the animation
$("#button1").fadeIn(); // and fade in the button
};
// On click, pass the length of the message to the function
$(document).click(dialogue.bind(null, message.length));
// Hide the button on page load
$("#button1").hide();
<!DOCTYPE=HTML>
<html>
<head>
<title>Sandbox</title>
<link rel="stylesheet" href="mainstyle.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
</head>
<body>
<p id="pid"></p>
<button id="button1">Ooh, here's one! Click to see what it does!</button>
</body>
</html>
You can simply ask for another parameter in dialogue() for the new message. You can then create an array of messages, from which you can choose whatever message you'd like to pass. This will ensure that all your messages are saved.
var messages = ["Message one", "Message two", "Message three"];

Javascript slideshow using timers

I'm apparently a bit of a dunce. I've been trying to get this to work as an onload slideshow that will randomly cycle through some images. I've looked through four different questions on here pertaining to how to change the src attribute using javascript and I think that I've avoided all of the problems that have been mentioned on those. The HTML calls the slideShow() function, but for the life of me I can't actually get the src to change and display on the page. Can someone please help me figure out what I've done wrong?
<script><!--
function slideShow()
{
window.setInterval("changeImage()", 5000);
}
function changeImage()
{
var imgSrcs["images//traps//1.jpg",
"images//traps//2.jpg",
"images//traps//3.jpg",
"images//traps//4.jpg"]
var i = Math.floor((Math.random() * 3));
var element = document.getElementById("slideShow").src;
element.innerHTML.src= imgSrcs[i];
}
--></script>
The HTML element that goes with this is:
<p><img src = "images//traps//1.jpg" alt = "Traps available for use" id = "slideShow"></p>
replace the following lines
var element = document.getElementById("slideShow").src;
element.innerHTML.src= imgSrcs[i];
with
var element = document.getElementById("slideShow");
element.src= imgSrcs[i];
I've assumed that slideShow refers to img tag id.

javascript : simple delayed image show

I'm trying to write a simple javascript snippet which delays the image loading by a certain number of millisecs below.
<html>
<head>
<script type="text/javascript">
function SetTimer()
{
var Timer = setInterval("showImage()",3000);
}
function showImage()
{
document.getElementById('showImage').style.visibility = 'visible';
}
</script>
</head>
<body onLoad="SetTimer()" style="visibility:hidden">
<div id=showImage>
<img src="gwyneth_paltrow_2.jpg">
</div>
</body>
</html>
Am I approaching this incorrectly?
thanks in advance
This is basically an OK approach.
There are some bugs, namely:
document.getElementByID('showImage')style.visibility = 'hidden';
getElementByID should be getElementById
needs a dot after ('showImage')
You are setting the visibility to 'hidden' in order to show it. Instead, you should start out as hidden, and then make it appear instead of disappear.
document.getElementById('showImage').style.visibility = 'hidden';
Well, the code is backwards given the stated goal of delaying the appearance of the image. If I just use your code as a basis, then I would have the visibility of the image as hidden, using CSS, and then trigger the display to visible on the timer.
However, having said that... This doesn't delay the loading of the image, it merely delays the display of it. The other way to handle it is to use the timer to load an Image object in Javascript and then insert it into the DOM. This, then, will actually delay the loading of the image for 3 seconds. Something like this:
function showImage()
{
var myImage = new Image();
myImage.src = "gwyneth_paltrow_2.jpg";
document.getElementById("showImage").appendChild(myImage);
}
I'm doing that from memory, so syntax may not be entirely correct.

how to preload large size image?

i have certain links, on mouse over of those links I am changing <div> background image
jQuery I have used is-
function imgchange()
{
$('.smenu li').mouseover( function(){
var src = $(this).find('a').attr('href');
$('.hbg').css('background-image', 'url(' + src + ')');
$(this).find('hbg').attr('title', 'my tootip info');
});
}
It is working fine but the problem is when I running it on server images takes 3-4 sec to be changed on change, but the second time I do mouse over images are getting changed instantly, I think this is because of browser stored images in cache. So I added one javascript to preload images on page onLoad() ivent -
<script language = "JavaScript">
function preloader()
{
heavyImage = new Image();
heavyImage.src = "images/soluinfo1.jpg";
heavyImage.src = "images/soluinfo2.jpg";
heavyImage.src = "images/soluinfo3.jpg";
heavyImage.src = "images/soluinfo4.jpg";
heavyImage.src = "images/soluinfo5.jpg";
heavyImage.src = "images/soluinfo6.jpg";
heavyImage.src = "images/soluinfo7.jpg";
}
</script>
<body onLoad="javascript:preloader()">
but this script has not solved my problem.what should I do?
#Richard's answer (sprites) is probably the best one for what you are after, but the reason your code is not working is that in most browsers, only the last heavyImage.src="" is given enough time to actually register with the browser as an actual request. You're creating only one Image object setting and resetting the .src attribute faster than the browser can request the files (I think modern JavaScript engines take the added step of removing all the intermediate .src statements specifically because of this).
There are a couple of ways to fix this. The easiest is to create multiple Image objects, one for each image. And the easiest way to do that is through something like this:
<script type="text/javascript">
function preloader()
{
function doPreload(strImagePath)
{
var heavyImage = new Image();
heavyImage.src = strImagePath;
}
var arrImages = ["images/soluinfo1.jpg","images/soluinfo2.jpg","images/soluinfo3.jpg","images/soluinfo4.jpg","images/soluinfo5.jpg","images/soluinfo6.jpg","images/soluinfo7.jpg"];
for (var i = 0; i < arrImages.length; i++) {
doPreload(arrImages[i]);
}
}
</script>
By putting the heavyImage variable inside its own function (remember to use the var keyword), you're ensuring that the Image object exists inside its own dedicated scope.
Another way to do this is to attach a "load" event listener to a single heavyImage. Every time the image finishes loading, go fetch the next image. The disadvantage to this method is that your images will be loaded one at a time (bad for navigation images, but great for, say, and image gallery), whereas the first technique will fetch the images in parallel (typicallly four at a time).
You might find it easier to change your approach and use CSS sprites (and another article). Then you would just have one image referenced, and you use CSS to set which part of that image gets shown in which scenario.
This assumes that the images you're using are under your control and you can use an image editor to combine them into one large image.

Categories