It's a simple exercise in which I want to hide a link I put in my Html file.
But make it appear after a timer has run out in my function.
This is the javascript bit
(below is the html bit)
var i = 10;
var time;
var countdown = document.getElementById("countdown");
var link = document.getElementById("link");
function MyFunction3() {
document.getElementById("imageoef").style.visibility="visible";
link.style.visibility="hidden";
i--;
countdown.innerHTML= i;
time = setTimeout ("MyFunction3();",1000);
if (i < 1) {
countdown.innerHTML="";
document.getElementById("imageoef").style.visibility="hidden";
link.style.visibility="visible";
}
}
HTML
<img src="images/loading.gif" alt="Loading..." id="imageoef" style="visibility:hidden" />
<form method="post">
<input onclick="MyFunction3();" type="button" value="start download" />
</form>
<div id="countdown">
<a id="link" href="http://freelanceswitch.com/freelance-freedom/freelance-freedom-2/" >Your download is ready!</a>
</div>
HTML:
<input type="button" onclick="hideLink()" value="Start" />
<p id="timer"></p>
<a id="link" href="">This link is hidden for 10 seconds.</a>
JavaScript:
var timeLeft = 10;
var count;
window.hideLink = function hideLink()
{
document.getElementById("link").style.visibility = "hidden";
count = setInterval (decrementTimer, 1000);
setTimeout (showLink,1000 * timeLeft);
};
function decrementTimer()
{
timeLeft = timeLeft - 1;
document.getElementById("timer").innerHTML = timeLeft + " seconds";
if(timeLeft <= 0)
{
window.clearInterval(count);
document.getElementById("timer").style.visibility = "hidden";
}
}
function showLink()
{
document.getElementById("link").style.visibility = "visible";
}
http://jsfiddle.net/rPnNr/4/
If you have place the javascript in the header section your code may not work. Because you are storing the countdown and link element value at the page loading. At that time if your elements has not get loaded to the page your countdown and link vars going to be null. better thing is access your elemet after your button click.
var i = 10;
var time;
var countdown = document.getElementById("countdown");
var link = document.getElementById("link");
function MyFunction3() {
countdown = document.getElementById("countdown");
link = document.getElementById("link");
document.getElementById("imageoef").style.visibility="visible";
link.style.visibility="hidden";
i--;
countdown.innerHTML= i;
time = setTimeout ("MyFunction3();",1000);
if (i < 1) {
countdown.innerHTML="";
document.getElementById("imageoef").style.visibility="hidden";
link.style.visibility="visible";
}
}
Your code doesn't work because it sets the countdown div's innerHTML to '', but the link was inside that div, so gets deleted and you can't then make it reappear just by setting its visibility. You could fix it just by putting the link outside of the div in the HTML.
<img src="images/loading.gif" alt="Loading..." id="imageoef" style="visibility:hidden"
/>
<form method="post">
<input id="myInput" type="button" value="start download" />
</form>
<div id="countdown">
</div><a id="link" href="http://freelanceswitch.com/freelance-freedom/freelance-freedom-2/">Your download is ready!</a>
While I was at it I altered your script a bit... (jsfiddle)
var i = 10,
time;
function E(id) {return document.getElementById(id) }
E('myInput').onclick = function () {
E('imageoef').style.visibility = 'visible';
E('link').style.visibility = 'hidden';
time = setInterval(function () {
i--;
E('countdown').innerHTML = i;
if (i < 1) {
clearInterval(time);
E('countdown').innerHTML = '';
E('imageoef').style.visibility = 'hidden';
E('link').style.visibility = 'visible';
}
}, 1000);
}
Actually the other changes are all non-essential but some explanation anyway:
you ideally want 2 functions, not just 1 - the first to trigger the countdown and the second for each time the counter decreases
setInterval is more useful than setTimeout here, as it recurs automatically and you don't need to keep setting it; however you do then need to use clearInterval to stop the timer. In your original code you were doing nothing to stop the timer so it would just carry on indefinitely (but with the effects hidden).
I preferred to set onclick in javascript rather than having an onclick attribute of the html tag. But your original method does also work.
(Here is your original code with only the necessary changes to make it work.)
Related
I'm tying to create a countdown timer for online test using JavaScript in asp.net core.
I want it to change every 1 second without refreshing the page.
when I run the program it doesn't show me the countdown.
This my javascript code:
<script type="text/javascript">
countdown = function () {
var current = parseInt(document.getElementById("timerLabel").innerHTML);
document.getElementById("left").innerHTML = current;
if (current > 0) {
setTimeout('countdown()', 1000); // run every second
}}
This is my view:
I used foreach loop to show this.
<div class="panel-footer">
<p> #item.Grade</p>
<p> #item.StartTime</p>
<p id="EndTime"> #item.EndTime</p>
<span id="timerLabel">#ViewBag.LeftTime</span>
<p id="left"></p>
</div>
Do not get the timerLabel value inside the function unless you also set it
Use interval and clear it when done
let current = parseInt(document.getElementById("timerLabel").innerHTML);
const countdown = function() {
document.getElementById("left").innerHTML = --current || "Done"; // using current when 0 it is false
if (current <= 0) clearTimeout(tId); // stop the interval
};
const tId = setInterval(countdown, 1000)
<span id="timerLabel">10</span>
<p id="left"></p>
In the head section:
var countdownTimer; <br/>
countdownTimer = 45; <br/>
function makeCountdown() { <br/>
countdownTimer = countdownTimer - 1; <br/>
}
setInterval(makeCountdown, 1000);
<br/><br/>
In the body section of the page:
document.write(countdownTimer);<br/>
function updateCountdown() { <br/>
document.replace(countdownTimer); <br/>
}
<br/><br/>
setInterval(updateCountdown, 1000);
<br/><br/>
I've checked in the browser console and the countdownTimer variable goes down each second, but where I'm struggling is on how to update the variable on the page in real time.
I've had a long look and I can't find anything here or elsewhere online that can help me out, I'm also fairly new to javascript. Many thanks for any help!
Make changes to the Element rather than document itself
There is no replace method for document
There is no point having 2 intervals if duration is identical
Note: Make sure you place script as last child of body or else, DOM api will try toa ccess the element before DOM is ready which will return null result for document.getElementById('elem')
var countdownTimer;
var elem = document.getElementById('elem');
countdownTimer = 45;
function makeCountdown() {
countdownTimer = countdownTimer - 1;
elem.textContent = countdownTimer;
}
setInterval(makeCountdown, 1000);
elem.textContent = countdownTimer;
<span id='elem'><span>
A little addition to Rayon's answer. To stop countdown when timer reach 0
var timer=45;
var intervalId;
function countdown(){
$('#elem').text(timer);
if(timer==0){
clearInterval(intervalId);
}
timer--;
}
intervalId=setInterval(countdown,1000);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.2.3/jquery.min.js"></script>
<span id="elem"></span>
Hey i am currently trying to get a program running in javascript i want the program to display the 4 images one after each other with the single press of a button and then after the 4 images have cycled through i want them to stop cycling and i cant seem to do it this is my code i currently have:
<html>
<head>
<script>
var images = ["image1.png","image2.png","image3.png","image4.png"];
var imagenum = 0;
var timer;
function imageCycle()
{
if(++imagenum == 4)
imagenum = 0;
document.image.src = images[imagenum];
timer = setTimeout("imageCycle()",1000);
}
</script>
</head>
<body>
<img src="image1.png" name="image" width=800 height=600>
<form>
<input type="button" value="images" name="cycle images" onclick="imageCycle()">
</form>
</body>
</html>
any help is appreciated many thanks!
In your code you continue to schedule the function, that's why the images continue to rotate.
If you want to stop at the forth image displayed, you have to put the setTimeout line in an else statement.
if (++imagenum == 4) {
imagenum = 0;
} else {
document.image.src = images[imagenum];
timer = setTimeout("imageCycle()",1000);
}
Another point, that other users notice and I just report here in my answer.
You use the string:
imageCycle()
as the first argument of setTimeout, insted you should use just the function name.
timer = setTimeout(imageCycle, 1000);
Currently making a basic game. The idea: click as many images in a set time as possible. I wrote some basic code for the timer and click counter. The problem I am having is that after the timer runs to zero and alerts "game over", the player can still click the image and add more to their score.
//Start button hidden after click
function hideBtn() {
document.getElementById("toggle").style.visibility="hidden";
}
//Countdown begins, goes to zero, alerts "game over"
function countdown(secs, elem) {
var element = document.getElementById(elem);
element.innerHTML = "Time: " + secs + " seconds";
secs--;
var timer = setTimeout('countdown(' + secs + ' ,"' + elem + '")', 1000);
if (secs <0) {
clearTimeout(timer);
alert("Game OVER!");
//element.innerHTML = "<h1> GAME OVER!</h1>";
};
}
//Click counter linked to multiple images
function clickdone() {
var hero = document.getElementById("hero");
var counter = document.getElementById("counter");
var count = counter.innerHTML;
count++;
counter.innerHTML = count;
}
<!--Linking countdown() to html-->
<div class="clock">
<div id="status"></div>
<button id="toggle" onclick="countdown(10,'status'), hideBtn()";>START</button>
</div>
<!--Example of one of the clickcounter images being linked to clickdone() and not counting more than one click-->
<div>
<img id="hero" src="images/img1.jpg" style="height:100px; width:100px;"
onclick="clickdone(); this.onclick=null;"/>
</div>
<!--click counter to html-->
<div class="statPanel">
<span id="counter">0</span>
</div>
I am looking for some help linking the countdown() and clickdone() so that when the timer/countdown() hits zero and alerts "game over", the clickdone() becomes inactive but will still show the total clicks.
The simplest thing to do might be to add a flag for the game being over.
Just add a boolean for game over that is initially false and set it to true when the game is over. Then just check if the boolean is true before allowing more clicks.
When secs goes below 0, you can nullify the onclick attribute of img#hero around the same time that you clear the timer and display the game over message.
if (secs < 0) {
document.getElementById('hero').onclick = null; // <---new code
clearTimeout(timer);
alert("Game OVER!");
//element.innerHTML = "<h1> GAME OVER!</h1>";
};
By the way, check out WindowTimers.setInterval().
Repeatedly calls a function or executes a code snippet, with a fixed
time delay between each call. Returns an intervalID.
Rather than repeatedly calling setTimeout every second, you may find it cleaner to just set an interval, store the returned interval ID and then eventually clear it.
TL;DR
Use the <element>.addEventListener("click", myHandler) and <element>.removeEventListener("click", myHandler) to allow/avoid click on <element>.
It's a little dirty ;)
First of all, no JavaScript in your DOM so your current HTML should be:
<div class="clock">
<div id="status"></div>
<button id="toggle">START</button>
</div>
<div>
<img id="hero" src="images/img1.jpg" width="100" height="100" />
</div>
<div class="stat-panel">
<span id="counter">0</span>
</div>
There are 4 areas implicated in your request:
A button start.
An image.
A countdown.
A counter.
So select each Node.
// Prepare your elements
var timer = document.getElementById("timer"),
toggle = document.getElementById("toggle"),
hero = document.getElementById("hero"),
counter = document.getElementById("counter");
After, we see 7 actions possible:
Init the game (used when game is reset)
Start the game
Set countdown current value -1
Add a point.
Allow click on the button.
Delete click on the button.
Perform a GameOver
So create functions by intentions:
// Prepare your actions
function gameStart (actions) {
toggle.addEventListener("click", function callee() {
toggle.style.display = "none";
toggle.removeEventListener("click", callee);
actions();
});
}
function initGame() {
timer.innerHTML = "";
toggle.style.display = "";
}
function gameOver() {
alert("Game OVER!");
}
function countdown(secs, reachZeroCallback) {
function removeSecond(next) {
timer.innerHTML = "Time: " + secs + " seconds";
setTimeout(function () {
secs--;
if (secs !== 0) {
next(next);
} else {
reachZeroCallback();
}
}, 1000);
}
removeSecond(removeSecond);
}
function addPoint() {
counter.innerHTML = +counter.innerHTML + 1;
avoidGainPoint();
}
function allowGainPoint() {
hero.addEventListener("click", addPoint);
}
function avoidGainPoint() {
hero.removeEventListener("click", addPoint);
}
And just use your actions !
// Write your Game
gameStart(function () {
allowGainPoint(avoidGainPoint);
countdown("10", function () {
initGame();
gameOver();
})
});
See this codepen to see game in action: http://codepen.io/anon/pen/KdJWYW
If you proceed by intentions (actions) you will be able to quickly change the behavior of your code.
Example: If you move avoidGainPoint from addPoint to countdown callback you will able to perform more one click until the countdown reach 0.
More advice
- Not write text into JavaScript code.
- Not use style but a class to profile all your visual state for a Node element.
I have 3 divs in a html page, 2 divs should be hiddent always but theire content should be displayed in another div and this content should be changed every x seconds. Hows that possible using jquery/javascript?
<div id="contentA">
<!-- Some contents goes here, and it should be hidden -->
</div>
<div id="contentB">
<!-- Some contents goes here, and it should be hidden -->
</div>
<div id="displayArea">
<!-- switch between contentA and contentB on a timer say every 5 seconds -->
</div>
Do not use the .html() function to copy content from one place to another. HTML is a serialisation format designed to carry DOM structures from a server to a client. Once the page is in a DOM structure you should manipulate that DOM structure directly using DOM methods. Using .html() to serialise a DOM node and then recreate it somewhere else risks losing things like event handlers, other hidden data, etc.
On that basis, to copy the current contents of a div into another:
var $contents = $('#contentA').contents().clone(); // copy the source element's contents
$('#displayArea').empty().append($contents); // drop them into the destination
In full:
(function() {
var delay = 3000;
var state = 0;
(function next() {
state = 1 - state;
var src = state ? '#contentA' : '#contentB';
var $contents = $(src).contents().clone();
$('#displayArea').empty().append($contents);
setTimeout(next, delay);
})();
})();
Try this :)
<div id='a' style='display: none;'>this is a</div>
<div id='b' style='display: none;'>this is b</div>
<div id='show'></div>
<script>
$(document).ready(function(){
var count = 0;
var content = '';
var j = setInterval(function () {
count++;
if(count%2===0){
content = $('#a').html();
}else{
content = $('#b').html();
}
$('#show').html(content);
}, 5000);
});
</script>
Try this:
var toggle = false;
$("#displayArea").html($("#contentA").html());
setInterval(function() {
$("#displayArea").html(toggle ? $("#contentA").html() : $("#contentB").html());
toggle = !toggle;
}, 5000);
Working DEMO
I don't know if this is what you need but this script should work:
check = true;
$(document).ready(function(){
setInterval(function(){
if(check) {
check = false;
$('#displayArea').html("a");
}
else {
check = true
$('#displayArea').html("b");
}
}, 5000);
});
function doSlides() {
var msg = messages.shift();
messages.push(msg);
$('#displayArea').html(msg);
};
var messages = [
$('#contentA').find('p').html(),
$('#contentB').find('p').html()
];
Demo:
http://jsfiddle.net/8Ux3L/
Here's one way to do it using setInterval():
var divs = $('div[id^="content"]').hide(),
i = 0;
function cycle() {
$("#displayArea").html(divs.eq(i).html());
i = ++i % divs.length; // increment i, and reset to 0 when it equals divs.length
}
setInterval(cycle, 2000); //Cycle every 2 seconds
Wrapping in a self executing function:
(function cycle() {
$("#displayArea").html(divs.eq(i).html());
i = ++i % divs.length; // increment i, and reset to 0 when it equals divs.length
setTimeout(cycle, 2000);
})();
DEMO
Try following code
<!DOCTYPE html>
<html>
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js" ></script>
<script>
var divSelected = "A";
function switch1()
{
if (divSelected == "A")
{
$("#displayArea").text($("#contentA").text());
divSelected = "B";
}
else
{
$("#displayArea").text($("#contentB").text());
divSelected = "A";
}
}
$(document).ready(function()
{
var test = setInterval( "switch1()" , 5000);
});
</script>
</head>
<body>
<div id="contentA" style = "display:none;">
Contect A
</div>
<div id="contentB" style = "display:none;">
Content B
</div>
<div id="displayArea">
</div>
</body>
</html>
Use an interval to trigger a function every x seconds, then jQuery replaceWith to swap the divs. If you don't want to replace the actual node but just the contents, then .html() is probably the way to go.