This code executes the "Click" function, but only one time. I would like it to repeated the click function until the timeout occurs.
I wanted to try setInterval instead of setTimeout, but was afraid I would create a race condition.
var M = 12; // january=1
var d = 29; // 1st=1
var h = 11; // 24h time
var m = 12;
var s = 0;
// How long after the target to stop clicking, in milliseconds.
var duration = 100000;
// How long prior to the start time to click, in milliseconds, to
// account for network latency.
var networkLatency = 150;
// HTML ID of the button to click.
var element = "btnbookdates";
// =====================================
// End configuration section
// =====================================
function getMillisecondsLeft() {
var nowDate = new Date();
var targetDate = new Date(y,M-1,d,h,m,s);
return targetDate - nowDate;
}
function click() {
var button = document.getElementById('btnbookdates');
if ( button ) {
window.console.log('clicked at '+getMillisecondsLeft());
button.click();
} else {
window.console.log('nothing to click at '+getMillisecondsLeft());
}
}
if (getMillisecondsLeft() > 0) {
window.console.log('queueing at '+getMillisecondsLeft());
setTimeout(click, getMillisecondsLeft() - networkLatency);
} else if (-getMillisecondsLeft() <= duration) {
click();
} else {
window.console.log('all done at '+getMillisecondsLeft());
}```
If I understood your question correctly, you want the click to stop when everything is done, i.e the else part at the end. You could try something like this:
var M = 12; // january=1
var d = 29; // 1st=1
var h = 11; // 24h time
var m = 12;
var s = 0;
// How long after the target to stop clicking, in milliseconds.
var duration = 100000;
// How long prior to the start time to click, in milliseconds, to
// account for network latency.
var networkLatency = 150;
// HTML ID of the button to click.
var element = "btnbookdates";
// =====================================
// End configuration section
// =====================================
function getMillisecondsLeft() {
var nowDate = new Date();
var targetDate = new Date(y,M-1,d,h,m,s);
return targetDate - nowDate;
}
function click() {
var button = document.getElementById('btnbookdates');
if ( button ) {
window.console.log('clicked at '+getMillisecondsLeft());
button.click();
} else {
window.console.log('nothing to click at '+getMillisecondsLeft());
}
}
var timer ={};
if (getMillisecondsLeft() > 0) {
window.console.log('queueing at '+getMillisecondsLeft());
timer = setInterval(click, getMillisecondsLeft() - networkLatency);
} else if (-getMillisecondsLeft() <= duration) {
click();
} else {
clearInterval(timer);
window.console.log('all done at '+getMillisecondsLeft());
}
Related
var hoursCounter = document.getElementById('hours-counter')
var minutesCounter = document.getElementById('minutes-counter')
var secondsCounter = document.getElementById('seconds-counter')
var hoursInput = document.getElementById('hours-input')
var minutesInput = document.getElementById('minutes-input')
var secondsInput = document.getElementById('seconds-input')
function setCountdownTimer() {
// code to set the timer values
hoursCounter.innerText = hoursInput.value
minutesCounter.innerText = minutesInput.value
secondsCounter.innerText = secondsInput.value
}
function startTimer() {
//code to start the Timer
}
function stopTimer() {
// code to stop the timer
}
`I'm a beginner in Js....! I manage to show the input values but confused in hours, minutes, seconds....!!
Thanks for help...`
There is a variable which contains event time. I want to redirect user if event time + 04:38 is more than current time.
Below is the code i have tried:
var deadline = getDayInstance("Monday","08:00:59")
function getDayInstance(day,time) {
const days = {"Sunday":0,"Monday":1,"Tuesday":2,"Wednesday":3,"Thursday":4,"Friday":5,"Saturday":6};
if(days[day]!==undefined)
var dayINeed = days[day];
else
var dayINeed = 2; // for Tuesday
const today = moment().tz("America/Los_Angeles").isoWeekday();
var dt;
// if we haven't yet passed the day of the week that I need:
if (today <= dayINeed) {
dt = moment().tz("America/Los_Angeles").isoWeekday(dayINeed).format('YYYY-MM-DD')+"T"+time;
}
else {
dt = moment().tz("America/Los_Angeles").add(1, 'weeks').isoWeekday(dayINeed).format('YYYY-MM-DD')+"T"+time;
}
console.log("Event Time: "+dt);
var maxLimit = Date.parse(moment(time,'HH:mm:ss').tz("America/Los_Angeles").add({"hours":4,"minutes":43,"seconds":33}).format("YYYY-MM-DDTHH:mm:ss"));
var now = Date.parse(moment().tz("America/Los_Angeles").format('YYYY-MM-DDTHH:mm:ss'));
if(maxLimit < now)
{
dt = moment().tz("America/Los_Angeles").add(1, 'weeks').isoWeekday(dayINeed).format('YYYY-MM-DD')+"T"+time;
window.setVideo = false;
}
console.log(moment(time,'HH:mm:ss').tz("America/Los_Angeles").add({"hours":4,"minutes":43,"seconds":33}).format("YYYY-MM-DDTHH:mm:ss"));
console.log(moment().tz("America/Los_Angeles").format('YYYY-MM-DDTHH:mm:ss'));
return dt;
}
var maxLimit = Date.parse(moment(deadline,'YYYY-MM-DDTHH:mm:ss').add({"hours":4,"minutes":43,"seconds":33}).format("YYYY-MM-DDTHH:mm:ss"));
var now = Date.parse(moment().tz("America/Los_Angeles").format('YYYY-MM-DDTHH:mm:ss'));
if(maxLimit>=now){
var redirectTo = $("#lp-pom-button-673").attr('href');
if(redirectTo.length > 3){
window.location.href = redirectTo;
}
else{
window.location.href = "https://******/";
}
}
I need to maintain timezone in calculation.
I got the answer of this after refining the process theoretically and then try to implement it in JS. Below is the new code that can be used for this.
var deadline = getDayInstance("Tuesday", "02:32:00");
var maxLimit,now;
function getDayInstance(day,time) {
const days = {"Sunday":0,"Monday":1,"Tuesday":2,"Wednesday":3,"Thursday":4,
"Friday":5,"Saturday":6};
if(days[day]!==undefined)
var dayINeed = days[day];
else
var dayINeed = 2; // for Tuesday
const today = moment().tz("America/Los_Angeles").isoWeekday();
var dt;
// if we haven't yet passed the day of the week that I need:
if (today <= dayINeed) {
dt = moment().tz("America/Los_Angeles").isoWeekday(dayINeed)
.format('YYYY-MM-DD')+"T"+time;
}
else {
dt = moment().tz("America/Los_Angeles").add(1, 'weeks')
.isoWeekday(dayINeed).format('YYYY-MM-DD')+"T"+time;
}
var d = new Date(dt);
d.setHours(d.getHours() + 4);
d.setMinutes(d.getMinutes() + 43);
d.setSeconds(d.getSeconds() + 32);
max = Date.parse(d);
now = Date.parse(moment().tz("America/Los_Angeles").format('YYYY-MM-DDTHH:mm:ss'));
if(maxLimit < now)
{
dt = moment().tz("America/Los_Angeles").add(1, 'weeks')
.isoWeekday(dayINeed).format('YYYY-MM-DD')+"T"+time;
}
return dt;
}
if(maxLimit>=now){
var redirectTo = $("#lp-pom-button-673").attr('href');
if(redirectTo.length > 3){
window.location.href = redirectTo;
}
else{
window.location.href = "https://******/";
}
}
var startTime = parent.startTime;
var endTime = parent.endTime;
var divID = '#'+parent.divId;
var description = parent.description;
do {
var currentTime1 = $('video').get(0).currentTime;
if(currentTime1 >= startTime) {
console.log('in if');alert('hi');
parent.$(divID).append(description);
}
setTimeout(function(){$('video').get(0).currentTime = $('video').get(0).currentTime + 1; currentTime1 = parseInt($('video').get(0).currentTime); }, 1000);
} while (currentTime1 <= endTime);
parent.$(divID).empty(); console.log('at end');
the above code stops responding and debuger shows this line var currentTime1 = $('video').get(0).currentTime;
Your code gets to infinite loop, because of
do {
var currentTime1 = $('video').get(0).currentTime;
} while (currentTime1 <= endTime);
It's executed as fast as your browser allows, so it get's stuck, because setTimeout will be executed after 1s and your currentTime1 will never change.
Please change logic - use video events, like timeupdate
var startTime = parent.startTime;
var endTime = parent.endTime;
var divID = '#'+parent.divId;
var description = parent.description;
var myVar = setInterval(check,1000);
function check()
{
var currentTime1 = parseInt($('video').get(0).currentTime);
if(currentTime1 >= parent.endTime)
{
clearInterval(myVar);
parent.$(divID).empty();
}
else if(currentTime1 >= parent.startTime)
{
parent.$(divID).empty();
parent.$(divID).append(description);
}
}
this code works without loop construct. setInterval() works for repeating the action again and again.
I have two count-down timers in my website. One timer would start automatically, but the next one should only start only after the 1st is completed. This should loop on forever, i.e. starting one clock after another.
Here is the code which I tried:
function count() {
var startTime = document.getElementById('hms').innerHTML;
var pieces = startTime.split(":");
var time = new Date();
time.setHours(pieces[0]);
time.setMinutes(pieces[1]);
time.setSeconds(pieces[2]);
var timedif = new Date(time.valueOf() - 1000);
var newtime = timedif.toTimeString().split(" ")[0];
document.getElementById('hms').innerHTML = newtime;
if (newtime !== '00:00:00') {
setTimeout(count, 1000);
} else {
count1();
}
}
count();
function count1() {
var startTime = document.getElementById('hms1').innerHTML;
var pieces = startTime.split(":");
var time = new Date();
time.setHours();
time.setMinutes(pieces[1]);
time.setSeconds(pieces[2]);
var timedif = new Date(time.valueOf() - 1000);
var newtime = timedif.toTimeString().split(" ")[0];
document.getElementById('hms1').innerHTML = newtime;
if (newtime !== '00:00:00') {
setTimeout(count, 1000);
} else {
count();
}
}
HTML:
<div id="hms">00:00:10</div>
<div id="hms1">00:02:10</div>
I am unable to make this work. Help!!
Your current code is nearly there - with a couple of small issues:
time.setHours is missing a parameter on line 23, should be as follows:
var time = new Date(); time.setHours(pieces[0]);
Line 30 should call the alternate function:
setTimeout(count1, 1000);
Only one counter should be running at a time, so no need to for the last line (count1()).
Here's an updated JSBin.
However, a DRY solution here would be much more appropriate to avoid having to manage two functions:
var currentTimer = 'hms';
var alternateTimer = 'hms1';
function count() {
var timer = document.getElementById(currentTimer);
var startTime = timer.innerHTML;
var pieces = startTime.split(':');
var time = new Date();
time.setHours(pieces[0]);
time.setMinutes(pieces[1]);
time.setSeconds(pieces[2]);
var timedif = new Date(time.valueOf() - 1000);
var newtime = timedif.toTimeString().split(' ')[0];
// Update DOM
timer.innerHTML = newtime;
if(newtime === '00:00:00') {
// Swap the two timers
currentTimer = [alternateTimer, alternateTimer = currentTimer][0];
}
setTimeout(count, 1000);
}
count();
Hope that helps!
count should start a timeout to run count1, and the converse:
initial_count = 5; // say 5 sec. count-down
initial_count1 = 7;
ic = initial_count;
function count() {
ic--
if (ic>=0)
setTimeout(count, 1000); // refresh every 1sec.
else {
ic = initial_count1;
count1();
}
}
function count1() {
ic--
if (ic>=0)
setTimeout(count1, 1000); // refresh every 1sec.
else {
ic = initial_count;
count();
}
}
count(); // start the first alarm.
Add all the remaining of your logic...
function count() {
var startTime = document.getElementById('hms').innerHTML;
var pieces = startTime.split(":");
var time = new Date(); time.setHours(pieces[0]);
time.setMinutes(pieces[1]);
time.setSeconds(pieces[2]);
var timedif = new Date(time.valueOf() - 1000);
var newtime = timedif.toTimeString().split(" ")[0];
document.getElementById('hms').innerHTML=newtime;
if(newtime!=='00:00:00'){
setTimeout(count, 1000);
}else
{
count1();
}
}
count();
function count1() {
var startTime = document.getElementById('hms1').innerHTML;
var pieces = startTime.split(":");
var time = new Date(); time.setHours();
time.setMinutes(pieces[1]);
time.setSeconds(pieces[2]);
var timedif = new Date(time.valueOf() - 1000);
var newtime = timedif.toTimeString().split(" ")[0];
document.getElementById('hms1').innerHTML=newtime;
if(newtime!=='00:00:00' && newtime!=='00:00:01' ){
setTimeout(count, 1000);
}else
{
count();
}
}
count1();
*For reference I'm using iron router.
Instead of a sign in page I have this global sign in form embedded in an nav (aka on every page).
Right now I'm doing a really hacky refresh to reload the page once a user logs in.
I would like to just reload to the template aka not refresh the whole page.
Basically just want the templates rendered function to rerun on login.
Here's my current login code:
'submit #login': function(event, template){
event.preventDefault();
var handle = template.find('#usernameLogin').value;
var secretKey = template.find('#passwordLogin').value;
Meteor.loginWithPassword(handle, secretKey, function(err){
if (err) {
alert(err);
}else{
$('#close').click();
/* replace this with reactive ajax or whatever when you can! */
Meteor._reload.reload();
}
});
},
My render function which I think may be the real issue now:
Template.tournament.rendered = function () {
thisCampaign = this.data;
var self = this;
if (this.data.tournament.live) {
/* if theres a registered user */
if (Meteor.userId()) {
/* Select a winner box */
var participants = $('.participant-id');
var currentParticipant;
var nextRound;
var thisMatch;
var nextMatch;
var bracket;
participants.map(function(index, value){
if ($(value).text() === Meteor.userId()) {
if ($(value).parent().find('.participant-status').text() === 'undetermined') {
nextRound = $(value).parent().find('.participant-round').text();
thisMatch = $(value).parent().find('.participant-match').text();
bracket = $(value).parent().parent().parent().find('.participant');
};
};
});
nextRound = parseInt(nextRound) + 1;
nextMatch = Math.round(parseInt(thisMatch)/2) - 1;
if (parseInt(thisMatch) % 2 != 0) {
currentParticipant = 0;
}else{
currentParticipant = 1;
}
var winnerOptions = '';
var winnerBox = $('<div class="select-winner">');
if (bracket) {
bracket.map(function(index, value) {
winnerOptions += '<span class="winner-option"> '+$(value).find('.participant-title').text()+' <div class="winner-info"> '+$(value).find('a').html()+' </div> </span>'
});
winnerBox.append(winnerOptions);
$($($('.round'+nextRound).find('li')[nextMatch]).find('.participant')[currentParticipant]).removeClass('loser').addClass('undetermined');
$($($('.round'+nextRound).find('li')[nextMatch]).find('.participant')[currentParticipant]).find('a').addClass('tooltip').html(winnerBox);
};
}else{
}
}else{
/* Tournament Start Time */
var tournamentStartTime = function(){
var d = new Date();
var n = d.getTime();
var currentTime = TimeSync.serverTime(n);
var startTime = self.data.card.startTime;
var difference = startTime - currentTime;
var hoursDifference = Math.floor(difference/1000/60/60);
difference -= hoursDifference*1000*60*60
var minutesDifference = Math.floor(difference/1000/60);
difference -= minutesDifference*1000*60
var secondsDifference = Math.floor(difference/1000);
/* if ends (make tournament live server side?) */
if (hoursDifference < 0 || minutesDifference < 0 || secondsDifference < 0) {
Meteor.clearInterval(tStartTime);
Session.set("tournamentStartTime", false);
}else{
if (hoursDifference < 10) {hoursDifference = "0"+hoursDifference;}
if (minutesDifference < 10) {minutesDifference = "0"+minutesDifference;}
if (secondsDifference < 10) {secondsDifference = "0"+secondsDifference;}
var formattedTime = hoursDifference + ':' + minutesDifference + ':' + secondsDifference;
Session.set("tournamentStartTime", formattedTime);
}
};
Session.set("tournamentStartTime", '00:00:00');
tournamentStartTime();
var tStartTime = Meteor.setInterval(tournamentStartTime, 1000);
/* Allow new user sign up */
var alreadySignedUp = false;
var usersSignedUp = $('.participant-id')
usersSignedUp.map(function (index, user) {
if ($(user).text().trim() === Meteor.userId()) {
alreadySignedUp = true;
}
});
if (this.data.card.host != Meteor.user().username && !(alreadySignedUp)) {
var openSlots = [];
var allSlots = $('.participant');
allSlots.map(function (index, participant) {
if ($(participant).find('.participant-title').text().trim() === '' && !($(participant).hasClass('loser'))) {
openSlots.push(participant);
}
});
openSlots.map(function (openSlot, index) {
$(openSlot).removeClass('winner').addClass('undetermined');
});
}
/* if theres a registered user */
if (Meteor.userId()) {
}else{
}
}
};
From what i can see there, your rendered function would not work as you expect as the template may render while the loggingIn state is still occuring...
My suggestion would be to use something along the lines of {{#if currentUser}} page here{{/if}} and then put the code you are trying to run in the rendered in a helper inside that currentUser block that way it would only display and be called if there is a logged in user, otherwise it would not show up and you would not need to re-render the page to perform any of that.
Basically once the user has logged in, any helper (other than rendered) that has the Meteor.userId() or Meteor.user() functions being called would re-run automatically, otherwise you could perform login actions inside a Tracker.autorun function if they are global to your app per client.