JavaScript Function Issue (dates) - javascript

I'm having issues with my JavaScript code. I need to make code that does the following:
Click an image twice within 3 seconds to make the image disappear
Click it once to reappear
I've got it close to working...I'm just having issues with the date. I don't know how to keep the date from the first click. My code right now is just creating a new start date each click which is what I don't want.
Code thus far:
var imgNext = -1;
var start = new Date ( );
function disappear ()
{
var end = new Date ();
imgNext++;
if (imgNext == 2)
{
document.getElementById("myPicture").style.visibility="visible";
imgNext = -1;
}
if (imgNext == 1 && (end-start <3000))
{
document.getElementById("myPicture").style.visibility="hidden";
}
start = new Date ();
}
In the code the image changes even if the clicks are over 3 seconds apart because I'm creating a new START date every time the function is triggered. How do I resolve this?

Here is answer, with a working example: http://jsfiddle.net/yS5bs/2/
document.getElementById("disappear").onclick = function() {
var lastClick = this.attributes["click-time"],
click = new Date().getTime(),
timeout = parseInt(this.attributes["data-timeout"].value);
if(lastClick && (click - lastClick) < timeout && this.style.opacity == 1) {
this.style.opacity = 0;
this.attributes["click-time"].value = null;
return;
}
else {
this.attributes["click-time"] = click;
}
if(this.style.opacity == 0) {
this.style.opacity = 1;
this.attributes["click-time"] = null;
return;
}
};
basically I am assigning the onclick, and getting the click times, if within the set timeout (milliseconds) then it hides, otherwise, it shows again, as per spec

Related

Countdown not reseting after click

Pressing the button it generates a countdown to request a new password. After this gets to 0 you get a new link to request it. The issue is when during existing countdown I am pressing the button. It seems somehow I am running in the same time 2 counters and not sure how to fix this. Can you please help:
https://codepen.io/acode2/pen/poaWpmv
<form class="olr-form">
<input
data-sc-field-name="secondsToNextOTP"
value="30"
>
<p class="passcodeReRequest">Don't have a valid passcode?</p>
<button type="submit" class="button__next button__test">Test</button>
</form>
const opt = () => {
$('.test').remove();
$('.otpLinkAvailable').remove();
let gCountdownTimerHandle = 0;
let gDateTimeForNextOTP = null;
// getting the seconds to cowntdown
let secsToNextOTP = $("[data-sc-field-name=secondsToNextOTP]").val() * 1;
if (secsToNextOTP) {
let passCodeResendlink = $(".passcodeReRequest");
Date.prototype.addSecs = function (s) {
this.setTime(this.getTime() + (s * 1000));
return this;
}
// this function is polled and updates the status of time until a new OTP request can be made by the user
function showTimeToWaitForOTP() {
try {
const linkAvailableInTag = $(".otpLinkAvailable");
const secondsToNextOTP = Math.round((gDateTimeForNextOTP - new Date()) / 1000);
if (linkAvailableInTag && linkAvailableInTag.length > 0) {
if (secondsToNextOTP > 0) {
linkAvailableInTag.text(" you can re-request a passcode in " + secondsToNextOTP + " seconds");
} else {
clearInterval(gCountdownTimerHandle);
linkAvailableInTag.text("");
linkAvailableInTag.after(" <a class='test' href='javascript:document.location = document.location+\"&resendOTP=true\"'>Send a new passcode</a>");
}
}
else {
clearInterval(gCountdownTimerHandle);
}
} catch { // any errors, cancel the timeout
clearInterval(gCountdownTimerHandle);
}
}
// // check if we need to trigger the OTP countdown timer
if (passCodeResendlink && passCodeResendlink.length > 0 && secsToNextOTP >= 0) {
gDateTimeForNextOTP = new Date().addSecs(secsToNextOTP);
passCodeResendlink.append("<span class='otpLinkAvailable'></span>");
gCountdownTimerHandle = setInterval(showTimeToWaitForOTP, 500); // issue countdown
}
}
}
$(".button__test").click(function(e) {
e.preventDefault();
opt();
});
gCountdownTimerHandle should be outside the opt() function. Each time you are clicking the button - you are resetting gCountdownTimerHandle to 0 at line number 3 inside opt() function. That is why your clearInterval is not capturing the actual id of setInterval and hence it is not getting cleared.
Hope it helps!
You just need a check to see if the countdown is already running and not start the countdown if it is - right now it just starts a new interval, that runs side-by-side with the old one(s) for every time you click it.

Chrome Extensions: Javascript not not running clearInterval();

I'm trying the make a chrome extension in javascript. So far, my popup.js looks like this:
let bg;
let clock;
document.addEventListener('DOMContentLoaded', function() {
document.getElementById('button1').addEventListener('click', butClicked);
bg = chrome.extension.getBackgroundPage();
//clock = document.getElementById("label1");
});
let timeStamp;
let isClockRunning = false;
function butClicked() {
let test = bg.getURL();
document.getElementById('test').innerHTML = test;
timeStamp = new Date();
isClockRunning = !isClockRunning;
runCheckTimer();
}
function runCheckTimer() {
var handle;
if(isClockRunning == true) {
handle = setInterval(updateClock, 1000);
}
else if(isClockRunning == false) {
clearInterval(handle);
handle = 0;
}
}
function updateClock() {
let seconds = bg.returnTimeSince(timeStamp);
document.getElementById("label1").innerHTML = "Seconds: " + seconds;
}
The program works just fine when I click the button once; it starts the timer. But when I click the button the second time, timeStamp gets set to 0, but the updateClock keeps running at the same interval; the interval doesn't get cleared even though I'm toggling the isClockRunning boolean. It's almost as if javascript is forgetting to run the else if part in runCheckTimer(). How can I fix this?
EDIT: On a sidenote, am I doing the timer thing the right way? Or is there a better way to do it? I basically want a timer to keep ticking every second since you've pressed the button, and then when you click it again it'll stop and reset to 0.
You have scoped handle to runCheckTimer. When runCheckTimer starts, it will create a new handle every time.
Move handle outside of the function.
var handle;
function runCheckTimer() {
if(isClockRunning == true) {
handle = setInterval(updateClock, 1000);
}
else if(isClockRunning == false) {
clearInterval(handle);
handle = 0;
}
}

Map data example with slider in d3

I tried to implement a basic slider function to this example
var slider = d3.slider()
.axis(false).min(minDate).max(maxDate).step(secondsInDay)
.on("slide", function(evt, value) {
temp = moment(value,"x").utc().format("MM");
console.log(temp);
//tempVal = moment(temp).unix()*1000;
dataChoro = countries.properties.filter(function(d){
return d.properties[attributeArray[temp]]
});
});
d3.select('#slider3').call(slider);
But I can't read countries. What do I have to change to make it running? I try to use the play function of this example but instead of the button playing I'd like to use the slider to trigger the events
function animateMap() {
var timer; // create timer object
d3.select('#play')
.on('click', function() { // when user clicks the play button
if(playing == false) { // if the map is currently playing
timer = setInterval(function(){ // set a JS interval
if(currentAttribute < attributeArray.length-1) {
currentAttribute +=1; // increment the current attribute counter
} else {
currentAttribute = 0; // or reset it to zero
}
sequenceMap(); // update the representation of the map
d3.select('#clock').html(attributeArray[currentAttribute]); // update the clock
}, 2000);
d3.select(this).html('stop'); // change the button label to stop
playing = true; // change the status of the animation
} else { // else if is currently playing
clearInterval(timer); // stop the animation by clearing the interval
d3.select(this).html('play'); // change the button label to play
playing = false; // change the status again
}
});
}
Gist Any tips?
When you want to use the same code of your clock you can try this
var slider = d3.slider()
.axis(false).min(minDate).max(maxDate).step(secondsInDay)
.on("slide", function(evt, value) {
temp = moment(value,"x").utc().format("MM");
if(currentAttribute < attributeArray.length-1) {
console.log(currentAttribute);
currentAttribute = temp-1; // increment the current attribute counter
} else {
currentAttribute = 0; // or reset it to zero
}
sequenceMap(); // update the representation of the map
d3.select('#clock').html(attributeArray[currentAttribute]); // update the clock
});
d3.select('#slider3').call(slider);

SetTimeOut speeds Up with multiple tabs opened

I have a timer ticker on Layout(MVC4.0) (With 1 Second Interval) page and it works fine when only 1 page of website(In one tab) is opened
var timeOutMinutes = 10;
var timeOutSeconds = timeOutMinutes * 60;
localStorage.setItem("SessionCounter", timeOutSeconds);
var popUpShown = false;
var logOutCalled = false;
$(document).ready(function () {
setInterval(TimerDecrement, 1000);
});
function TimerDecrement() {
if (timeOutSeconds > 0) {
if (parseInt(localStorage.getItem("SessionCounter"), 10) > 0) {
timeOutSeconds = parseInt(localStorage.getItem("SessionCounter"), 10);
}
timeOutSeconds--;
localStorage.setItem("SessionCounter", timeOutSeconds);
}
else {
if (!logOutCalled) {
logOutCalled = true;
LogOut();
}
else {
logOutCalled = true;
}
}
document.getElementById("seconds").innerHTML = timeOutSeconds;
document.getElementById("secondsIdle").innerHTML = timeOutSeconds;
if (timeOutSeconds < 500) {
//alert(history.length);
popUpShown = true;
$("#pnlPopup").dialog("open");
}
else {
if ($("#pnlPopup").dialog("isOpen")) {
popUpShown = false;
$("#pnlPopup").dialog("close");
}
}
}
But when I open multiple tabs of website timer jumps to decrease quickly.
How can I maintain the timer to decrement Uniformly even if website is opened in multiple tabs?
FIDDLE
The problem is that you are using the counter that is being decremented is common to all tabs, because it is kept in LocalStorage. So the solution really depends on what you intention is for the decrement counter.
If the intention is for each session (each tab) to have it's own separate counter, then you would be better served using a variable instead of LocalStorage -- or alternatively, use a unique session id for each counter in LocalStorage.
If the intention is to have all tabs share the same decrement counter, but for it to only be decremented once per second regardless of how many tabs are open, then perhaps you want to store the counter as well as the last decrement time.
EDIT: Here is a forked fiddle that might do what you need:
http://jsfiddle.net/y68m4zwr/8/
The gist of it is to add:
var lastUpdated = localStorage.getItem("SessionCounterUpdatedOn"),
now = new Date(), shouldCheck = false;
if (lastUpdated == null) {
localStorage.setItem("SessionCounterUpdatedOn", now);
} else if (now.getTime() - new Date(lastUpdated).getTime() >= 1000) {
// set this immediatedly so another tab checking while we are processing doesn't also process.
localStorage.setItem("SessionCounterUpdatedOn", now);
shouldCheck = true;
}
which checks for a last updated record for the counter and it if was updated less that second ago, it just updates the time left, otherwise performs the logic to decrement.

How can i do button on hold for two second call function1 if less then two second call function2?

I have this button which is not working correctly for hold button for a period (but it works like click only).
Where i was trying to do if the button is hold for greater/equal then 2 seconds then callfunction1, if the button was pressed less then 2 seconds then callfuntion2.
var clickDisabled = false;
function clickLocker() {
/* #Button: 2 seconds */
clickDisabled = true;
setTimeout(function(){clickDisabled = false;}, 2000);
}
function callfunction1() { // you have hold he button for greater then or equal 2 second }
function callfunction2() { // you have hold the button less then 2 second }
$('.button').live("click",function()
{
if (clickDisabled) {
alert("locked for 2 second");
return;
}
clickLocker();
});
I think this solution should work. I have not tested it but it should give you the right idea.
var startTime;
function callfunction1() { // you have hold he button for greater then or equal 2 second }
function callfunction2() { // you have hold the button less then 2 second }
function buttonDownEvent() {
var Time = new Date();
startTime = Time.getTime();
}
function buttonUpEvent() {
if(new Date().getTime() - startTime < 2000)
callfunction2()
else
callfunction1()
}
$('.button').live("mousedown",function()
{
buttonDownEvent();
});
$('.button').live("mouseup",function()
{
buttonUpEvent();
});
Listen for both events, mousedown and mouseup, measuring the time between both:
var timeDown;
var timeUp;
$('.button').live("mousedown",function(){
timeDown = event.timeStamp;
});
$('.button').live("mouseup",function(){
timeUp = event.timeStamp;
time = timeUp-timeDown;
if (time>2000){
function1();
}else{
function2();
}
});
please note that event.timeStamp wont work well in firefox. For firefox you can do (new Date).getTime();
You can do this using events to the mouseup and mousedown events and timing the difference between them. Also, you need to remember which element caused the click - if the user released the mouse on a different element then it should just do the "non 2-second hold" function. A JSFiddle showing this working is available here: http://jsfiddle.net/35rw3/6/.
That was a great suggestion from slash. This is how you can do this
var clickstart;
var clickstop;
$("a").on('mousedown', function(e) {
clickstart = e.timeStamp;
}).on('mouseup', function(e) {
clickstop = e.timeStamp- clickstart
if(clickstop >= 2000) two()
else one();
});
Demo
Updates:
It might be necessary to track the mouse movement like #MarkRhodes wrote in his comments. So for that, check this update

Categories