How to execute onclick methood inside javascript code - javascript

I want execute onclick event after the 5 second timer gone and second button enabled.. Here is my code.
Download Video
Javascript code
<script>
var towait = 5;
var selector = "#downloadvideo";
function counter() {
if (towait == 0) {
$(selector).text("Start Download");
var srclink = '<?= $url;?>';
$(selector).attr('href', srclink).prop('href', srclink).prop('disabled', false);
return;
}
$(selector).text("Wait " + towait + " s").prop('disabled', true);
towait--;
setTimeout(counter, 1000);
}
$(selector).one('click', function(e) {
counter();
return false;
});
</script>

Try to add setInterval and clearInterval functions to your code. Below is a simple 10 seconds timer just to demonstrate. For full disclosure, not all of the code is my own some of it I've copied from this answer.
var timeleft = 10;
var b = document.querySelector('#btn');
b.addEventListener('click', () => {
var downloadTimer = setInterval(function(){
if(timeleft <= 0){
clearInterval(downloadTimer);
}
document.getElementById("progressBar").value = 10 - timeleft;
timeleft -= 1;
}, 1000);
});
input[type='number'] {
border: 0;
font-size: 15px;
}
input[type=number]::-webkit-inner-spin-button {
-webkit-appearance: none;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<div>
<button id='btn'>Click</button>
<input type='number' value="0" max="10" id="progressBar"></input>
</div>
</body>
</html>

You can do something like this. Just update the DownloadVideo function to what you need to happen when the 'Start Downloading' button is pressed.
EDIT:
Using an <a> tag with a href instead.
let waitTime = 5 // Time to wait in seconds before download is available
const selector = document.getElementById('downloadvideo')
selector.onclick = () => {
selector.textContent = 'Wait ' + waitTime + ' s'
selector.disabled = true
selector.onclick = () => {}
const inter = setInterval(() => {
waitTime--
if (waitTime == 0) {
clearInterval(inter)
selector.textContent = 'Start Downloading'
selector.href = 'https://www.google.com' // replace with the desired url
} else {
selector.textContent = 'Wait ' + waitTime + ' s'
}
}, 1000)
}
<button>
<a id="downloadvideo" class="btn btn-primary btn-lg"> Download Video </a>
</button>

Related

How to toggle a button with Javascript

I want to create a phone-like stopwatch using HTML, CSS, and vanilla JavaScript. The one I have already done does the task, but I don't want a separate button for stopping and starting. How could I make a button that changes from start to stop and stop to start?
Here is my HTML Code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div class="wrapper">
<h1>Stopwatch</h1>
<h2>Vanilla JavaScript Stopwatch</h2>
<p><span id="seconds">00</span>:<span id="tens">00</span></p>
<button id="button-start">Start</button>
<button id="button-stop">Stop</button>
<button id="button-reset">Reset</button>
</div>
</body>
</html>
Here is my JavaScript code:
window.onload = function () {
var seconds = 00;
var tens = 00;
var appendTens = document.getElementById("tens")
var appendSeconds = document.getElementById("seconds")
var buttonStart = document.getElementById('button-start');
var buttonStop = document.getElementById('button-stop');
var buttonReset = document.getElementById('button-reset');
var Interval ;
buttonStart.onclick = function() {
clearInterval(Interval);
Interval = setInterval(startTimer, 10);
}
buttonStop.onclick = function() {
clearInterval(Interval);
}
buttonReset.onclick = function() {
clearInterval(Interval);
tens = "00";
seconds = "00";
appendTens.innerHTML = tens;
appendSeconds.innerHTML = seconds;
}
function startTimer () {
tens++;
if(tens <= 9){
appendTens.innerHTML = "0" + tens;
}
if (tens > 9){
appendTens.innerHTML = tens;
}
if (tens > 99) {
console.log("seconds");
seconds++;
appendSeconds.innerHTML = "0" + seconds;
tens = 0;
appendTens.innerHTML = "0" + 0;
}
if (seconds > 9){
appendSeconds.innerHTML = seconds;
}
}
}
Define a boolean to track if the clock is running or not and combine the start and stop function into one: something like this:
var clockStarted = false;
buttonStart.onclick = function() {
clearInterval(Interval);
if (!clockStarted) {
Interval = setInterval(startTimer, 10);
clockStarted = true;
} else {
clockStarted = false;
}
}
buttonReset.onclick = function() {
clearInterval(Interval);
tens = "00";
seconds = "00";
appendTens.innerHTML = tens;
appendSeconds.innerHTML = seconds;
clockStarted = false;
}
You could make your play-button invisible after clicking on it (buttonStart.style.dispaly = "none") and enable your stop-button (buttonStop.style.dispaly = "block") and do the same in reverse in your stop function.
Another possible way would be to use only one button and save the state of your player in a variable (i.e. a boolen isPlaying). Then you'd only need one onPress method which starts or stops the player according to isPlaying. Youd also need to change the element or the icon on you button accoring to this variable.

How can I reset time in a simple game?

I've tried make simple clicking game (if time count is higher than 5, the game is over, but you can reset time if you click generated element).
Unfortunately time is still counting. How can I fix this?
Why do I get this error?
Uncaught TypeError: Cannot set property 'textContent' of null
at js.js:8
at js.js:49
(function() {
const startGame = document.querySelector('button')
let time = 0;
let roll = true;
let h2 = document.querySelector('h2')
h2.textContent = time;
const timeFlow = () => {
time++
}
const resetTime = () => {
time = 0;
console.log(time)
}
const rollBall = () => {
if (roll == true) {
let divCreator = document.createElement('div')
document.body.appendChild(divCreator)
divCreator.classList.add('square')
divCreator.style.backgroundColor = 'red'
divCreator.style.top = Math.floor(Math.random() * 99) + '%'
divCreator.style.left = Math.floor(Math.random() * 99) + '%'
divCreator.addEventListener('click', letsPlay)
divCreator.addEventListener('click', resetTime)
setInterval(timeFlow, 1000)
} else if (roll == false) {
roll = true;
}
}
const letsPlay = (e) => {
let start = document.body.removeChild(e.target)
roll = false;
if (time >= 5) {
alert('U lost')
} else {
rollBall()
}
}
startGame.addEventListener('click', rollBall)
})();
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<button>Generate</button>
<script src='js.js'></script>
<h2>Time</h2>
</body>
</html>
You can use the load event instead of an IIFE before the elements exist.
Also your div needs dimensions
Also I assume you want the time in the H2?
Also you need position absolute to move the div
Lastly I clear the interval before a new one
window.addEventListener("load", function() {
const startGame = document.querySelector('button')
const h2 = document.querySelector('h2')
let tId;
let time = 0;
let roll = true;
h2.textContent = time;
const timeFlow = () => {
time++
h2.textContent = time;
}
const resetTime = () => {
time = 0;
}
const rollBall = () => {
if (roll == true) {
let divCreator = document.createElement('div')
document.body.appendChild(divCreator)
divCreator.classList.add('square');
divCreator.style.height = '50px'
divCreator.style.width = '50px'
divCreator.style.backgroundColor = 'red'
divCreator.style.position = 'absolute'
divCreator.style.top = Math.floor(Math.random() * 99) + '%'
divCreator.style.left = Math.floor(Math.random() * 99) + '%'
divCreator.addEventListener('click', letsPlay)
divCreator.addEventListener('click', resetTime)
clearInterval(tId); // remove any running interval
tId = setInterval(timeFlow, 1000)
}
roll = !roll;
}
const letsPlay = (e) => {
let start = document.body.removeChild(e.target)
roll = false;
if (time >= 5) {
alert('U lost')
} else {
roll = true; // right?
rollBall()
}
}
startGame.addEventListener('click', rollBall)
})
body {
height: 100%;
background-color: yellow;
}
<button>Generate</button>
<h2>Time</h2>
Your HTML code is in the wrong order: the <h2> element and the <script> element should be switched.
You should change it like this:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<button>Generate</button>
<h2>Time</h2>
<script src='js.js'></script>
</body>
</html>

Javascript Start/Stop button changes innerHTML and starts timer but doesn't fulfil any of the other part of function

I have a button which I am trying to use as a start and stop for an event which starts or stops a countdown timer. However it currently only starts and changes to the stop but will not change back to start or stop the timer from counting down.
Is there a better way of doing this? I've also included the reset button as I've tried to reset things when it it's pushed but it currently just changes back to the start, but the start won't fire again after I have done this.
((d) => {
let btn = d.getElementById("btn");
let reset = d.getElementById("reset");
let countdown = d.getElementById("countdown");
let counter;
let startTime = 1500;
let timerFormat = (s) => {
return (s - (s %= 60)) / 60 + (9 < s ? ":" : ":0") + s;
};
countdown.innerHTML = timerFormat(startTime);
let timer = () => {
startTime--;
countdown.innerHTML = timerFormat(startTime);
if (startTime === 0) clearInterval(counter);
};
btn.addEventListener("click", () => {
if (stop) {
start();
btn.innerHTML = "Stop";
} else {
stop();
btn.innerHTML = "Start";
}
});
let start = () => {
counter = counter || setInterval(timer, 1000);
};
let stop = () => {
clearInterval(counter);
counter = undefined;
};
reset.onclick = () => {
startTime = 1500;
countdown.innerHTML = timerFormat(startTime);
if (btn.innerHTML === "Stop") {
btn.innerHTML = "Start";
}
};
})(document);
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="../styles/styles.css" />
<script defer src="../JS/timer.js"></script>
</head>
<body>
<div id="countdown"></div>
<div class="btn__container">
<button class="btn" id="btn">Start</button>
<button class="btn" id="reset">Reset</button>
</div>
</body>
</html>
Your problem is in how you are determining whether to start or stop:
if (stop) {
stop is a function, so it has a "truthy" value and your if statement will always evaluate to true. Instead, check the existence of counter.
Other:
Don't use .innerHTML if you can help it and certainly not when the
string you are working with doesn't contain any HTML. .innerHTML
has security and performance implications. Instead, use
.textContent.
While a timer isn't going to be 100% accurate for timekeeping, you
can make the counter a little bit more accurate by having the
callback run just a little under every second. The reason being that
running every second means you run the risk of possibly skipping over
a second on the counter if the timer doesn't run exactly one second
later.
((d) => {
let btn = d.getElementById("btn");
let reset = d.getElementById("reset");
let countdown = d.getElementById("countdown");
let counter;
let startTime = 1500;
let timerFormat = (s) => {
return (s - (s %= 60)) / 60 + (9 < s ? ":" : ":0") + s;
};
countdown.textContent = timerFormat(startTime);
let timer = () => {
startTime--;
countdown.textContent = timerFormat(startTime);
if (startTime === 0) clearInterval(counter);
};
btn.addEventListener("click", () => {
if (counter) {
stop();
btn.textContent = "Start";
} else {
start();
btn.textContent = "Stop";
}
});
let start = () => {
counter = counter || setInterval(timer, 950);
};
let stop = () => {
clearInterval(counter);
counter = null;
};
reset.onclick = () => {
startTime = 1500;
countdown.textContent = timerFormat(startTime);
if (btn.textContent === "Stop") {
btn.textContent = "Start";
}
};
})(document);
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="../styles/styles.css" />
<script defer src="../JS/timer.js"></script>
</head>
<body>
<div id="countdown"></div>
<div class="btn__container">
<button class="btn" id="btn">Start</button>
<button class="btn" id="reset">Reset</button>
</div>
</body>
</html>

How to Redirect if no mouse movement and show current timer countown

I have this javascript to act as a countdown timer in a div, and simultaneously detecting mouse idleness.
var timer = null;
setInterval(function() {
var div = document.querySelector("#counter");
var count = div.textContent * 1 - 1;
div.textContent = count;
if (count == 0) {
window.location.href="https://example.com";
}
}, 1000);
function goAway() {
clearTimeout(timer);
timer = setTimeout(function() {
window.location.href="https://example.com";
}, 5000);
}
window.addEventListener('mousemove', goAway, true);
goAway();
If the user makes no mouse movement for more than 5 seconds, I want him to be redirected to another page. The example.com in this case. This part is working. However, I also intent for a right placed div to show the countdown to be redirected, and to disappear in case of .mousemove event. I cannot seem to get both of them working.
is it possible?
http://jsfiddle.net/9sAce/
Hope this helps. A few modifications done to goAway function.
var timer = null;
setInterval(function() {
var div = document.querySelector("#counter");
var count = div.textContent * 1 - 1;
div.textContent = count;
if (count == 0) {
window.location.href="https://example.com";
}
}, 1000);
function goAway() {
var div = document.querySelector("#counter");
div.innerText = "10";
clearTimeout(timer);
timer = setTimeout(function() {
if (div.innerText === "0")
window.location.href="https://example.com";
}, 5000);
}
window.addEventListener('mousemove', goAway, true);
goAway();
<div id="counter" style="border:1px solid black;width:100px">10</div>
Configurable:
Swap out .timer for #counter if that's your preference.
t tracks time
l is total time
h is url
Inside the interval n is the total time minus the current time t
v compares the calculation greater than 0 if false set n to 0 ( needed to prevent negative integers )
Update the DOM with the visual count
if n is equal to 0 redirect to the set URL.
(()=>{
t = 0;
l = 5;
h = 'https://example.com';
document.write('<h1 class="timer">'+l+'</h1>');
timer = document.querySelector('.timer');
setInterval(()=>{
t += 1;
n = (l - t);
v = n > 0 ? n : 0;
timer.innerText = v;
if(n === 0) {
window.location.href = h;
}
}, 1000);
document.addEventListener('mousemove', (e) => {
t = 0;
});
})();
Click here to see an example: https://codepen.io/DanielTate/pen/VMVMLa
You might try something like:
//<![CDATA[
// external.js
function countdown(outputElement, seconds){
var s = 5, bs = 5;
if(seconds){
s = bs = seconds;
}
function tF(){
outputElement.innerHTML = s = bs;
return setInterval(function(){
s--;
if(!s){
clearInterval(timer); location = 'https://example.com';
}
outputElement.innerHTML = s;
}, 1000);
}
var timer = tF();
onmousemove = function(){
clearInterval(timer); timer = tF();
}
}
var old = onload;
onload = function(){
if(old)old();
countdown(document.getElementById('counter'));
}
//]]>
/* external.css */
html,body{
padding:0; margin:0;
}
.main{
width:940px; padding:20px; margin:0 auto;
}
#counter{
font-size:80px;
}
<!DOCTYPE html>
<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'>
<head>
<meta http-equiv='content-type' content='text/html;charset=utf-8' />
<meta name='viewport' content='width=device-width' />
<title>simple countdown</title>
<link type='text/css' rel='stylesheet' href='css/external.css' />
<script type='text/javascript' src='external.js'></script>
</head>
<body>
<div class='main'>
<div id='counter'></div>
</div>
</body>
</html>

Re-starting a timer after stopping it

Problem: When I click my start button after stopping my timer, I can't seem to get the timer to resume.
Desired result: For any given timer, when I click the start button, after clicking the stop button, I want the time to resume where it left off.
I figured that when clicking the start button, it would just call the setInterval function again after being cleared, however, I am having issues figuring that out.
I have the stop event in each function in the same scope as the intervalID var's, which hold the setInterval functions itself. Which is why the stop button works. Calling the timer functions(setPomodoro, setLongBreak, setShortBreak) resets their timer's to the original state. I can't seem to grasp how to resume from the timer's time when it's stopped.
JSBIN: http://jsbin.com/bucalequsi/edit?html,js,output
Re-creation:
// Problem: Pomodor timer does not have functionality
// Solution: Add functionality to the pomodor timer.
// IF a break timer is running WHILE another is clicked, stop running timer, start clicked timer.
// Reset current interval time on reset button.
// If break buttons are clicked more than once, reset the time.
window.onload = function() {
var pomodoro = document.querySelector('#set-time'),
longBreak = document.querySelector('#long-brk'),
shortBreak = document.querySelector('#short-brk'),
stopButton = document.querySelector('#stop'),
startButton = document.querySelector('#start'),
resetButton = document.querySelector('#reset'),
container = document.querySelector('#container'),
actionButtons = document.querySelector('#buttons'),
timer = document.querySelector('#timer');
// Click event for break timers.
container.addEventListener('click', function(e) {
// store event target
var el = e.target;
if (el === pomodoro) {
setPomodoro();
} else if (el === longBreak) {
setLongBreak();
} else if (el === shortBreak) {
setShortBreak();
}
e.stopPropagation();
}, false);
// 1.1a Create a timer that counts down from 25 minutes.
function setPomodoro() {
var mins = 24;
var secs = 60;
var intervalID = setInterval(function() { //set unique interval ID for each SI func.
timer.innerHTML = mins + ':' + secs;
secs--;
if (secs === 0) {
mins--;
secs = 60;
}
}, 1000);
// 2.2 When stop button is clicked, timer stops
stopButton.addEventListener('click', function() {
clearInterval(intervalID);
}, false);
}
// 1.2a Create a timer that counts down from 10 minutes
function setLongBreak() {
var mins2 = 9;
var secs2 = 60;
var intervalID2 = setInterval(function() {
timer.innerHTML = mins2 + ':' + secs2;
secs2--;
if (secs2 === 0) {
mins2--;
secs2 = 60;
}
}, 1000);
stopButton.addEventListener('click', function(){
clearInterval(intervalID2);
}, false);
}
// 1.3a Create a timer that counts down from 5 minutes.
function setShortBreak() {
var mins3 = 4;
var secs3 = 60;
var intervalID3 = setInterval(function() {
timer.innerHTML = mins3 + ':' + secs3;
secs3--;
if (secs3 === 0) {
mins3--;
secs3 = 60;
}
}, 1000);
stopButton.addEventListener('click', function() {
clearInterval(intervalID3);
}, false);
}
};
HTML:
<!DOCTYPE html>
<html>
<head>
<title>Pomodoro Timer</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="normalize.css">
<link rel="stylesheet" href="main.css">
</head>
<body>
<div id="container">
<header>
<div id="header"><h1>Pomodoro Timer</h1></div>
</header>
<div class="row">
<ul id="breaks">
<li><input type="submit" value="Pomodoro" id="set-time"></li>
<li><input type="submit" value="Long Break" id="long-brk"></li>
<li><input type="submit" value="Short Break" id="short-brk"></li>
</ul>
</div>
<h1 id=timer></h1>
<div class="row">
<ul id="buttons">
<li><input type="submit" value="Start" id="start"></li>
<li><input type="submit" value="Stop" id="stop"></li>
<li><input type="submit" value="Reset" id="reset"></li>
</ul>
</div>
<footer>
<p>© Laere 2016</p>
</footer>
</div>
<script src="script.js"></script>
</body>
</html>
When the set... functions are started with the buttons, you always initialise the times to starting values. Instead, if there is a timer already running you have to parse the paused time string into minutes and seconds and use those values to set your vars mins and secs.
Maybe something like this will work?
function setPomodoro() {
if(timer.innerHTML.length > 0){
var t = timer.innerHTML.split(':');
var mins = parseInt(t[0]);
var secs = parseInt(t[1]);
}
else{
var mins = 24;
var secs = 60;
}
var intervalID = setInterval(function() { //set unique interval ID for each SI func.
timer.innerHTML = mins + ':' + secs;
secs--;
if (secs === 0) {
mins--;
secs = 60;
}
}, 1000);
// 2.2 When stop button is clicked, timer stops
stopButton.addEventListener('click', function() {
clearInterval(intervalID);
}, false);
}

Categories