Countdown timer working stop on chrome extensions. - javascript

I think that I will build chrome extensions to count down.
In case of the present code, if popup.html is closed, processing will be completed compulsorily.
In this case, is it better to write setInterval to background.js?
Moreover, I want you to teach whether what I should do concrete.
background.js
var num = window.localStorage.setItem("minite_num", 20);
default_count = num*60;
function count_start() {
count = default_count;
chrome.browserAction.setIcon({
path: {
"19": "img/icon_count19.png",
"38": "img/icon_count38.png"
}
});
}
function count_down() {
count--;
if (count <= 0) {
page_change();
count_stop();
}
}
popup.js
var bg = chrome.extension.getBackgroundPage();
var num = bg.num;
var start_btn = document.count_timer.start_btn;
var count_time = document.getElementById("counter");
document.addEventListener('DOMContentLoaded', function () {
load();
start_btn.addEventListener('click', start_display);
});
function timer_reset() {
timerID = 0;
}
function count_format(num) {
var tm,ts;
tm = Math.floor(num / 60); //分
ts = num % 60; //秒
if (ts < 10) ts = "0" + ts;
return tm + ":" + ts;
}
function load(){
display_num = bg.count_format(bg.default_count);
bg.timer_reset();
start_btn.disabled = false;
count_time.innerHTML = display_num;
}
function start_display() {
start_btn.disabled = true;
bg.count_start();
timerID = setInterval(function() {bg.count_down();count_time.innerHTML = bg.count;}, 1000);
}
popup.html
<form name="count_timer" class="count_timer">
<div id="counter" class="counter"></div>
<input type="button" name="start_btn" value="START">
</form>
Thanks.

use chrome storage / localStorage to remember your target time.
Use an interval from the popup to update your calculations. First time, the popup needs to read from storage and determine where the countdown is at.
Nothing needs to be done from background, unless you want to separate logic (as in MVC), then maybe do all storage stuff from background, and ask for it with messaging.
I have a published open-source chrome extension (plus for trello) with a count(up) timer feature that does something similar.

Related

Pure JavaScript: How to refresh page after countdown if the browser tab is active

I want to achieve the following scenario:
Set a timer of 60 seconds and start the countdown displaying the
timer. After the countdown is finished, refresh (not reload) the page
and restart the countdown timer and continue the process.
If the browser's tab is changed, after finishing the timer, refresh the
page and pause the timer, and only when the tab is active again refresh
the page and start the countdown timer again.
I have managed to achieve the first requirement like:
Result will Refresh in <span id="countdown"></span>
<script>
if (!document.hidden) {
function timedRefresh(e) {
var n = setInterval((function () {
e > 0 ? (e -= 1, document.getElementById("countdown").innerHTML = e) : (clearInterval(n), window.location.reload())
}), 1e3)
}
timedRefresh(59)
}
</script>
And is unable to achieve the second requirement. I have tried to implement the solution mentioned here: Is there a way to detect if a browser window is not currently active?
But it didn't work.
How do I achieve the requirements in pure JavaScript code?
The following code has solved this scenario. It's a little messy, but I think is understandable. We use both window.document.hasFocus() and the focus event to create this solution. I have changed the window.location.reload() methods to just consoles simulating a function that refresh the data inside the application, since is asked to us refresh (not reload).
function timedRefresh(intervalTime) {
let interval = null;
let currentTime = intervalTime;
const updateTimer = () => {
const countdownSpan = document.getElementById("countdown");
if (currentTime <= 0) {
console.log(`print refresh at ${new Date()}`); // refresh page
if (window.document.hasFocus()) {
currentTime = intervalTime;
} else {
clearInterval(interval);
interval = null;
currentTime = intervalTime;
}
}
if (!interval) {
countdownSpan.innerHTML = "#";
} else {
countdownSpan.innerHTML = currentTime;
currentTime -= 1;
}
};
interval = setInterval(updateTimer, 1000);
window.addEventListener("focus", () => {
if (!interval) {
interval = setInterval(updateTimer, 1000);
}
});
}
const TIMER_SECONDS = 5;
timedRefresh(TIMER_SECONDS);
Edit:
The answer above does not work with reloads using window.location.realod(). A code solving the issue may look like this:
const TIMER_SECONDS = 60;
/*
* Update span with current time
* `currentTime` is an integer bigger than zero or a string '#' meaning 'timer stopped'
*/
function updateDisplayTimer(currentTime){
const countdownSpan = document.getElementById("countdown");
countdownSpan.innerHTML = currentTime;
}
/*
* A timer with `loopDuration` seconds. After finished, the timer is cleared.
* `loopDuration` is an integer bigger than zero, representing the time duration in seconds.
*/
function timedRefresh(loopDuration) {
let currentTime = loopDuration;
let interval = setInterval(() => {
if (currentTime > 0) {
updateDisplayTimer(currentTime);
currentTime -= 1;
} else {
window.location.reload(); // refresh page
}
}, 1000);
window.addEventListener('load', () => {
if(window.document.hasFocus()){
timedRefresh(TIMER_SECONDS);
} else {
updateDisplayTimer("#");
clearInterval(interval);
interval = null;
}
});
window.addEventListener('focus', () => {
if(interval == null){
window.location.reload(); // refresh page
}
});
}
// exeute main fucntion
timedRefresh(TIMER_SECONDS);
Use window.document.hasFocus() to determine if the user is focused on your webpage or not.

How to make Javascript Count Up timer work

I am trying to implement a simple count up timer using Javascript and show the timer in the HTML page. This is my code:
var minutesLabel = document.getElementById("minutes");
var secondsLabel = document.getElementById("seconds");
var totalSeconds = 0;
setInterval(setTime, 1000);
function setTime()
{
++totalSeconds;
secondsLabel.innerHTML = pad(totalSeconds%60);
minutesLabel.innerHTML = pad(parseInt(totalSeconds/60));
}
function pad(val)
{
var valString = val + "";
if(valString.length < 2)
{
return "0" + valString;
}
else
{
return valString;
}
}
HTML:
<label id="minutes">00</label>
<label id="colon">:</label>
<label id="seconds">00</label>
But the timer is not working in the HTML. It stays at 00:00
Make sure the script is at the bottom on the body tag
The code you posted works exactly as you describe.
Check this fiddle, I just copy pasted it.
.
The code you mentioned is working perfectly fine in the snippets.

Loading/Buffering text while loading audio in html5 custom player with JavaScript

I found a custom html5 audio player and successfully redesigned it, now I want to add a "loading/buffering" text while player is loading audio (otherwise users may freak out because nothing happening after they hit play).
Here is the code to explain:
function calculateTotalValue(length) {
var minutes = Math.floor(length / 60),
seconds_int = length - minutes * 60,
seconds_str = seconds_int.toString(),
seconds = seconds_str.substr(0, 2),
time = minutes + ':' + seconds
return time;
}
function calculateCurrentValue(currentTime) {
var current_hour = parseInt(currentTime / 3600) % 24,
current_minute = parseInt(currentTime / 60) % 60,
current_seconds_long = currentTime % 60,
current_seconds = current_seconds_long.toFixed(),
current_time = (current_minute < 10 ? "0" + current_minute : current_minute) + ":" + (current_seconds < 10 ? "0" + current_seconds : current_seconds);
return current_time;
}
function initProgressBar() {
var player = document.getElementById('player');
var length = player.duration
var current_time = player.currentTime;
// calculate total length of value
var totalLength = calculateTotalValue(length)
jQuery(".end-time").html(totalLength);
// calculate current value time
var currentTime = calculateCurrentValue(current_time);
jQuery(".start-time").html(currentTime);
var progressbar = document.getElementById('seekObj');
progressbar.value = (player.currentTime / player.duration);
progressbar.addEventListener("click", seek);
if (player.currentTime == player.duration) {
$('#play-btn').removeClass('pause');
}
function seek(evt) {
var percent = evt.offsetX / this.offsetWidth;
player.currentTime = percent * player.duration;
progressbar.value = percent / 100;
}
};
function initPlayers(num) {
// pass num in if there are multiple audio players e.g 'player' + i
for (var i = 0; i < num; i++) {
(function() {
// Variables
// ----------------------------------------------------------
// audio embed object
var playerContainer = document.getElementById('player-container'),
player = document.getElementById('player'),
isPlaying = false,
playBtn = document.getElementById('play-btn');
// Controls Listeners
// ----------------------------------------------------------
if (playBtn != null) {
playBtn.addEventListener('click', function() {
togglePlay()
});
}
// Controls & Sounds Methods
// ----------------------------------------------------------
function togglePlay() {
if (player.paused === false) {
player.pause();
isPlaying = false;
$('#play-btn').removeClass('pause');
} else {
player.play();
$('#play-btn').addClass('pause');
isPlaying = true;
}
}
}());
}
}
initPlayers(jQuery('#player-container').length);
Player code (source) on CodePen
I want some text will be shown in the same "span" that shows
"start time" (please see CodePen) while media is loading;
The text " 'loading.' 'loading..' 'loading...' " must changing on
loop while media is loading;
When it is loaded the "loading" text must be changing on "start
time" as it is now.
So basically I wat to put some text in start time while it is not shows anything but zeroes
I'm new to JS
Thats why I need some help or point to right direction
You can use the "readyState" event of the audio player to show hide loading.
There is already a "SetInterval" even which is getting fired so in that we can add this code to show/hide the "Loading"
1st add the loading element(You can put it where ever you want"
<h3 id="loading" style="display:none;">Loading</h3>
Now let's add the code to check "readystate" inside "SetInterval"
if(player.readyState>0&&player.readyState<4){
$("#loading").show();
}
else{
$("#loading").hide();
}
You can read more about "readystate" here
/As per the request I have changed the code to use the start time as loading, to make it work we don't have to add anything inside html but need to do some changes in JS
First, add this inside "togglePlay" functions pay condition in the "else" block.
$(".start-time").html("Loading...");
After this inside "initProgressBar()" function replace the "jQuery(".start-time").html(currentTime);" with the below code
if (player.readyState === 4) {
jQuery(".start-time").html(currentTime);
}
so how it will work, When you click play button the start time text will show as "Loading" but once the file is loaded and the player is ready to play the text will be changed to "start time", Hope it works. Also updated the CodePen for better understanding
You can find the full code in the CodePen
You could use setInterval to cycle through the different 'loading' text and clearInterval when the player's play promise is done.
Here's a basic example:
var dots = 1;
var loading = setInterval(function(){
dots = (dots % 3) + 1;
$(".start-time").text("Loading" + Array(dots + 1).join("."));
console.log($(".start-time").text());
}, 250);
player.play().then(function() {
clearInterval(loading);
}).catch((error) => {
$(".start-time").text("Error loading");
});

How can I modify a variable on another site?

My son is doing times tables practice on this page, a timed test in which he gets 10 seconds for each sum.
https://www.timestables.com/speed-test/ - this is not my site or code, I have no direct control over the source code.
I want to give him a little more time per sum but I cannot find a way to modify the relevant code and make it work with 20 seconds instead of 10.
It looks to me like the relevant variable is maxTime (milliseconds) in this function, but nothing I do using the Chrome Developer Tools will modify this in a live running page to give 20 seconds instead of 10.
function startSom(){
vraagnr = vraagnr + 1;
if(vraagnr <= totaalSommen)
{
bezig = true;
$('#pbar_innerdiv').stop();
$('#pbar_innerdiv').css("width","100%");
$('#pbar_innerdiv').css("backgroundColor","#33BF00");
$('#pbar_innerdiv').css("borderColor","#33BF00");
if(mobiel){
$("#antwVak").html("");
}
else{
$("#antwoordI").val("");
$("#antwoordI").focus();
}
$('#pbar_innerdiv').stop();
start = new Date();
maxTime = 10000;
timeoutVal = Math.floor(maxTime/100);
var somT = sommen[vraagnr-1].split(",");
$('#somVak').html(somT[1]+"×"+somT[0]+"=");
$('#voortgangVak').html("Question "+vraagnr+" / "+totaalSommen+"<br />"+ punten + " points");
animateUpdate();
started = false;
}
else
{
showEindScherm();
}
}
Can anyone suggest what to do please?
You can copy the entire method, pase it into chrome devtools and change
function startSom() {
to
window.startSom = function() {
And obviously change your time from 10000 to 20000. This changes the amount of time it allows you to answer, but not the moving progress bar which will still only take 10 seconds.
Please paste this:
window.startSom = function(){
vraagnr = vraagnr + 1;
if(vraagnr <= totaalSommen)
{
bezig = true;
$('#pbar_innerdiv').stop();
$('#pbar_innerdiv').css("width","100%");
$('#pbar_innerdiv').css("backgroundColor","#33BF00");
$('#pbar_innerdiv').css("borderColor","#33BF00");
if(mobiel){
$("#antwVak").html("");
}
else{
$("#antwoordI").val("");
$("#antwoordI").focus();
}
$('#pbar_innerdiv').stop();
start = new Date();
maxTime = 20000;
timeoutVal = Math.floor(maxTime/100);
var somT = sommen[vraagnr-1].split(",");
$('#somVak').html(somT[1]+"×"+somT[0]+"=");
$('#voortgangVak').html("Question "+vraagnr+" / "+totaalSommen+"<br />"+ punten + " points");
animateUpdate();
started = false;
}
else
{
showEindScherm();
}
}
Here:
And if you want to make the progress bar following the new max Time, also paste this:
window.animateUpdate = function() {
if(bezig)
{
var now = new Date();
var timeDiff = now.getTime() - start.getTime();
if(!started){
$('#pbar_innerdiv').css("width", (100) + "%");
$('#pbar_innerdiv').animate({width: 0 + "%"},20000);
started = true;
}
perc = Math.round((timeDiff/maxTime)*100);
console.log(perc);
if(perc == 33)
{
$('#pbar_innerdiv').css("backgroundColor", "#FF9500");
$('#pbar_innerdiv').css("borderColor", "#FF9500");
}
if(perc== 66)
{
$('#pbar_innerdiv').css("backgroundColor", "#FF0000");
$('#pbar_innerdiv').css("borderColor", "#FF0000");
}
if (perc <= 100) {
//updateProgress(perc);
setTimeout(animateUpdate, timeoutVal);
}
else
{
bezig = false;
showTeLaat();
//alert("tijd is om");
}
}
}
There is a possibility to change files persistently in chrome devtools: Overrides.
If the script is in a seperate file you can change the maxTime directly there or if it is in a file, which needs to be reloaded you can edit any other .js and add an eventlistener there to change the startSom method on page load.

jquery: stopwatch

I'm using the stopwatch code I found here:
http://www.kellishaver.com/projects/stopwatch/
(function($) {
$.fn.stopwatch = function() {
var clock = this;
var timer = 0;
clock.addClass('stopwatch');
//console.log(clock);
// This is bit messy, but IE is a crybaby and must be coddled.
clock.html('<div class="display"><span class="hr">00</span>:<span class="min">00</span>:<span class="sec">00</span></div>');
clock.append('<input type="button" class="start" value="Start" />');
clock.append('<input type="button" class="stop" value="Stop" />');
clock.append('<input type="button" class="reset" value="Reset" />');
//console.log(clock.html());
// We have to do some searching, so we'll do it here, so we only have to do it once.
var h = clock.find('.hr');
var m = clock.find('.min');
var s = clock.find('.sec');
var start = clock.find('.start');
var stop = clock.find('.stop');
var reset = clock.find('.reset');
stop.hide();
start.bind('click', function() {
timer = setInterval(do_time, 1000);
stop.show();
start.hide();
});
stop.bind('click', function() {
clearInterval(timer);
timer = 0;
start.show();
stop.hide();
});
reset.bind('click', function() {
clearInterval(timer);
timer = 0;
h.html("00");
m.html("00");
s.html("00");
stop.hide();
start.show();
});
function do_time() {
// parseInt() doesn't work here...
hour = parseFloat(h.text());
minute = parseFloat(m.text());
second = parseFloat(s.text());
second++;
if(second > 59) {
second = 0;
minute = minute + 1;
}
if(minute > 59) {
minute = 0;
hour = hour + 1;
}
h.html("0".substring(hour >= 10) + hour);
m.html("0".substring(minute >= 10) + minute);
s.html("0".substring(second >= 10) + second);
}
};
})(jQuery);
And I use it like this:
<script type="text/javascript">
$('#clock1').stopwatch();
</script>
It works fine and I can stop it using the stop button. However I would like to be able to stop it programatically using javascript. Something like this:
<script type="text/javascript">
$('#clock1').stop();
</script>
I created the stop function but I cannot access the timer var defined in stopwatch(). How can I do it?
How about:
$('#clock1').find('.stop').trigger('click');
You can add a small API to the code and attach it using $.data:
var api = {
stop: function() {
stop.click(); // this should probably be improved, but you get the idea
}
};
$(clock).data('stopwatch', api);
Then use:
$('#clock1').data('stopwatch').stop();
You can also add the reset and start functions to the API using the same logic. A good thing here is that you can improve the execution code on a coffee break later without changing the way external programs uses the API.

Categories