Function in an object - javascript

JS-folks,
I've got a problem with a little test-script.
I've got this JS:
var button = {
lastClick: 0,
nowTime: new Date().getTime(),
go: function () {
var diff = this.nowTime - this.lastClick;
if (diff < 3000) alert('Too fast:' + diff / 1000);
lastClick = this.nowTime;
}.bind(this)
};
And this HTML:
<input type="button" value="Go" onClick="button.go();" />
The go-function should use the nowTime and lastClick values from my button-object but they are undefined. Can anybody help me?
JS-Fiddle

That's because this is undefined when you make the binding (so you're binding to window).
You can do this :
var button = {
lastClick: 0,
nowTime: new Date().getTime()
};
button.go = function () {
var diff = this.nowTime - this.lastClick;
if (diff < 3000) alert('Too fast:' + diff / 1000);
this.lastClick = this.nowTime;
}.bind(button);
You were also missing a this. before lastClick.
An alternative is to use a closure/factory :
var button = (function(){
var lastClick = 0;
var nowTime = new Date().getTime();
return {
go: function () {
var diff = nowTime - lastClick;
if (diff < 3000) alert('Too fast:' + diff / 1000);
lastClick = nowTime;
}
}
})();
A difference (which may or not be a benefit for you) is that the internal state of the button is hidden in this version (the fields are usually said to be "private").
If you want nowTime to always be the current time, don't store it :
var button = (function(){
var lastClick = 0;
return {
go: function () {
var nowTime = new Date().getTime();
var diff = nowTime - lastClick;
if (diff < 3000) alert('Too fast:' + diff / 1000);
lastClick = nowTime;
}
}
})();

Related

How to make multiple countdown timers at the same page using the codes below?

How to make multiple countdown timers at the same page using the codes below?
I tried to make another countdown timer by making another var start = document.getElementById("start2"); and var dis = document.getElementById("display2"); but when I click the 1 button only the second countdown timer is working,
var start1 = document.getElementById("start1");
var dis1 = document.getElementById("display1");
var finishTime1;
var timerLength1 = 10;
var timeoutID1;
dis1.innerHTML = "" + timerLength1;
if(localStorage.getItem('myTime')){
Update();
}
start1.onclick = function () {
localStorage.setItem('myTime', ((new Date()).getTime() + timerLength1 * 1000));
if (timeoutID1 != undefined) window.clearTimeout(timeoutID1);
Update();
}
function Update() {
finishTime1 = localStorage.getItem('myTime');
var timeLeft = (finishTime1 - new Date());
dis1.innerHTML = "" + Math.max(timeLeft/1000,0)
timeoutID1 = window.setTimeout(Update, 100);
}
var start2 = document.getElementById("start2");
var dis2 = document.getElementById("display2");
var finishTime2;
var timerLength = 100;
var timeoutID;
dis2.innerHTML = "" + timerLength;
if(localStorage.getItem('myTime')){
Update();
}
start2.onclick = function () {
localStorage.setItem('myTime', ((new Date()).getTime() + timerLength * 1000));
if (timeoutID != undefined) window.clearTimeout(timeoutID);
Update();
}
function Update() {
finishTime2 = localStorage.getItem('myTime');
var timeLeft = (finishTime2 - new Date());
dis2.innerHTML = "" + Math.max(timeLeft/1000,0)
timeoutID = window.setTimeout(Update, 100);
}
<span id="display2"></span><button id="start1">START1</button>
<br><br>
<span id="display2"></span><button id="start1">START1</button>
enter code here
You are using the same id for localStorage. Actually it is better to create isolated context through function or class, then it will be easier to handle as much counters as you wish. Also you can use setInterval instead of setTimer
One more tip: when you assign number to string field no need to write "" + value, because number authomatically will be converted into string
const createCounter = (startElementId, displayElementId, localStorageId, timerLength) => {
const startElement = document.getElementById(startElementId),
displayElement = document.getElementById(displayElementId)
let timeoutID
displayElement.innerHTML = timerLength
const storageValue = localStorage.getItem(localStorageId)
if (storageValue) startTimer()
startElement.onclick = () => {
const value = (new Date()).getTime() + timerLength * 1000
localStorage.setItem(localStorageId, value)
startTimer()
}
function startTimer () {
if (timeoutID) clearInterval(timeoutID)
timeoutId = setInterval(updateTime, 100)
}
function updateTime (finishTime) {
finishTime = finishTime || localStorage.getItem(localStorageId)
const timeLeft = finishTime - new Date()
displayElement.innerHTML = Math.max(timeLeft / 1000, 0)
}
}
// run first timer for elements with ids start1 and display1
createCounter('start1', 'display1', 'someId1', 10)
// run second timer for elements with ids start1 and display1
createCounter('start2', 'display2', 'someId2', 60)
html
<button id=start1>Start</button>
<div id=display1></div>
<button id=start2>Start</button>
<div id=display2></div>

Timer and localstorage issue

I am quite new to Javascript and web programming and currently learning localStorage and I have found some code and I tried to modify it. What I am trying to do, when the set time is up, I want to call another function named whatever function.. Please help.
Note: If there is any problem in terms of rule of Stack overflow, Let me know. I will edit & delete the question.
JS
var finishTime;
var timerLength = 10;
var timeoutID;
dis.innerHTML = "Time Left: " + timerLength;
if(localStorage.getItem('myTime')){
Update();
}
$('#save').click(function () {
localStorage.setItem('myTime', ((new Date()).getTime() + timerLength * 1000));
if (timeoutID != undefined) window.clearTimeout(timeoutID);
Update();
});
function Update() {
finishTime = localStorage.getItem('myTime');
var timeLeft = (finishTime - new Date().getTime());
dis.innerHTML = "Time Left: " + Math.max(timeLeft/1000,0);
if(timeLeft <= 0){
console.log('please work');
}else{
timeoutID = window.setTimeout(Update, 100);
}
}
view
<p id="display">Time Left
<p>
<button id="start">Start</button>
didn't try your code but this line:
var timeLeft = (finishTime - new Date());
shouldn't be?
var timeLeft = (finishTime - new Date().getTime());
added the .getTime()
edit:
function Update() {
finishTime = localStorage.getItem('myTime');
var timeLeft = (finishTime - new Date().getTime());
dis.innerHTML = "Time Left: " + Math.max(timeLeft/1000,0);
if (timeLeft <= 0){
localStorage.removeItem('myTime'); //<=remove
whateversomethingfunctuin();
// console.log('Seems');
} else {
//call only when needed
timeoutID = window.setTimeout(Update, 100);
}
}

.hide() div when timer reaches 0

I have been trying to make a timer disappear when it reaches 00:00 but everytime I try something it just hides the div right away.
Here is the code I am using:
$(document).ready(function(e) {
var $worked = $("#worked");
function update() {
var myTime = $worked.html();
var ss = myTime.split(":");
var dt = new Date();
dt.setHours(0);
dt.setMinutes(ss[0]);
dt.setSeconds(ss[1]);
var dt2 = new Date(dt.valueOf() - 1000);
var temp = dt2.toTimeString().split(" ");
var ts = temp[0].split(":");
$worked.html(ts[1] + ":" + ts[2]);
setTimeout(update, 1000);
}
setTimeout(update, 1000);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="worked">00:10</div>
I have created an example for you. For this example I have changed the timer's interval to 10ms so you can see the result quicker. Also instead of setting a setTimeout to run update inside the function update. You can use setInterval. I have also added a check inside the update function that checks if the time is 00:00. If it is true, then it invalidates the interval by calling clearInterval(timer); and runs $worked.hide()
$(document).ready(function (e) {
var $worked = $("#worked");
var timer = setInterval(update, 10);
function update() {
var myTime = $worked.html();
var ss = myTime.split(":");
var dt = new Date();
dt.setHours(0);
dt.setMinutes(ss[0]);
dt.setSeconds(ss[1]);
var dt2 = new Date(dt.valueOf() - 1000);
var temp = dt2.toTimeString().split(" ");
var ts = temp[0].split(":");
$worked.html(ts[1]+":"+ts[2]);
$worked.html(ts[1]+":"+ts[2]);
if(ts[1] === '00' && ts[2] === '00') {
clearInterval(timer);
$worked.hide();
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="worked">01:00</div>
Here's another approach :)
$(document).ready(function(e) {
var $worked = $("#timer");
var startTime = new Date().getTime();
var now, currentDistance;
setInterval(function update() {
now = new Date().getTime();
currentDistance = 10000 - now + startTime;
if (currentDistance > 0) {
$worked.html(parseInt(currentDistance / 1000) + " seconds, " + (currentDistance % 1000) + " ms left!");
} else {
$worked.hide();
}
}, 1);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="timer" style="background-color: rgb(190, 190, 220); width: 200px; text-align: center"></div>

Countdown timer for use in several places at same page

I want to make a countdown timer, that can be used on several places in the same page - so I think it should be a function in some way.
I really want it to be made with jQuery, but I cant quite make it happen with my code. I have e.g. 10 products in a page, that I need to make a countdown timer - when the timer is at 0 I need it to hide the product.
My code is:
$(document).ready(function(){
$(".product").each(function(){
$(function(){
var t1 = new Date()
var t2 = new Date()
var dif = t1.getTime() - t2.getTime()
var Seconds_from_T1_to_T2 = dif / 1000;
var Seconds_Between_Dates = Math.abs(Seconds_from_T1_to_T2);
var count = Seconds_Between_dates;
var elm = $(this).attr('id');
alert(elm);
countdown = setInterval(function(){
$(elm + " .time_left").html(count + " seconds remaining!");
if (count == 0) {
$(this).css('display','none');
}
count--;
}, 1000);
});
});
});
EDIT 1:
$(document).ready(function(){
$(".product").each(function(){
var elm = $(this).attr('id');
$(function(){
var t1 = new Date()
var t2 = new Date()
var dif = t1.getTime() - t2.getTime()
var Seconds_from_T1_to_T2 = dif / 1000;
var Seconds_Between_Dates = Math.abs(Seconds_from_T1_to_T2);
var count = Seconds_Between_dates;
alert(elm);
countdown = setInterval(function(){
$(elm + " .time_left").html(count + " seconds remaining!");
if (count == 0) {
$(this).css('display','none');
}
count--;
}, 1000);
});
});
});
Do you have any solutions to this?
I'd probably use a single interval function that checks all the products. Something like this:
$(function() {
/* set when a product should expire.
hardcoded to 5 seconds from now for demonstration
but this could be different for each product. */
$('.product').each(function() {
$(this).data('expires', (new Date()).getTime() + 5000);
});
var countdown_id = setInterval(function() {
var now = (new Date()).getTime();
$('.product').each(function() {
var expires = $(this).data('expires');
if (expires) {
var seconds_remaining = Math.round((expires-now)/1000);
if (seconds_remaining > 0) {
$('.time-left', this).text(seconds_remaining);
}
else {
$(this).hide();
}
}
});
}, 1000);
});
You could also cancel the interval function when there is nothing left to expire.
Your problem seems to be that this doesn't refer to the current DOM element (from the each), but to window - from setTimeout.
Apart from that, you have an unnecessary domReady wrapper, forgot the # on your id selector, should use cached references and never rely on the timing of setInterval, which can be quite drifting. Use this:
$(document).ready(function(){
$(".product").each(function(){
var end = new Date(/* from something */),
toUpdate = $(".time_left", this);
prod = $(this);
countDown();
function countdown() {
var cur = new Date(),
left = end - cur;
if (left <= 0) {
prod.remove(); // or .hide() or whatever
return;
}
var sec = Math.ceil(left / 1000);
toUpdate.text(sec + " seconds remaining!"); // don't use .html()
setTimeout(countdown, left % 1000);
}
});
});

Debugging JavaScript Timing Events

I'm having a problem with this JavaScript script. I've tried a number of things to get it to work. The alerts in there at current are there for debugging purposes, and seem to be failing to occur.
Help please?
function checkTime(this_time){
var the_string = "checkTime("+this_time+")";
var now = ((new Date()).getTime());
if(parseInt(now) >= parseInt(this_time)){
document.write("TIMEUP!");
}
alert(now);
alert(this_time);
var t = setTimeout(the_string,300);
}
var the_time = (((new Date()).getTime())+19000);
var the_string = "checkTime("+the_time+")";
var t = setTimeout(the_string,300);
Thanks,
Will.
Seems like you're looking for a countdown?
See this fiddle. The code is simplified to:
var bench = 19000 + new Date().getTime(),
timer = setInterval(
function(){
checkTime(bench);
}
, 1000
);
function checkTime(this_time){
var check = new Date - this_time;
if(check>=0){
alert('time\'s up!');
clearInterval(timer);
}
}
You should use setTimeout with closures instead of strings.
var now = new Date().getTime();
setTimeout(function(){
//your Javascript code here
//"now" can be used here as a closure
}, 300);
Here is a safer and self-contained version. A document.write after load will clear the page completely
http://jsfiddle.net/mplungjan/Zt5k7/
window.onload=function() {
var timer = function (endTime) {
var end = new Date(endTime);
var tId;
this.checkTime=function(){
var now = new Date();
document.getElementById("msg").innerHTML=now.toLocaleString();
if (now.getTime()>=end.getTime()) {
document.getElementById("msg").innerHTML="TIME's UP!";
clearInterval(tId);
}
}
tId = setInterval(this.checkTime,300);
}(new Date().getTime()+5000);
}
or for a proper countdown http://jsfiddle.net/mplungjan/Zt5k7/1/
window.onload=function() {
var timer = function (endTime) {
var end = new Date(endTime);
var tId;
this.checkTime=function(){
var now = new Date();
document.getElementById("msg").innerHTML=now.toLocaleString();
var diff = end.getTime()-now.getTime()
if (diff >= 1) document.getElementById("msg").innerHTML=parseInt(diff/1000)+1;
else {
document.getElementById("msg").innerHTML="TIME's UP!";
clearInterval(tId);
}
}
tId = setInterval(this.checkTime,300);
}(new Date().getTime()+9000);
}
I suppose the code could be made more simple to work.
function checkTime(this_time){
var now = ((new Date()).getTime());
if((now - this_time) >= 0){
document.write("TIMEUP!");
window.clearInterval(timer);
}
}
var t_t = (((new Date()).getTime())+19000);
var timer = window.setInterval(function(){
checkTime(t_t); }
, 300);
Cheers!

Categories

Resources