Answered by:
Why is my javascript interval timer flickering?

Question
-
User-462241089 posted
I am trying to add a idle timer to my web app that will trigger a message to the user asking if they want to remain logged in after one hour of inactivity. A 15 minute timer then runs on the message, and when it hits 0, the user is logged out.
All this code works, but the problem is that the clock displayed in the "logout-counter-span" in the message element is flickering with several numbers. I ran a debug on it and found that it is counting down from all the previous minutes. In the first minute, it is just 14, but then in the next minute, it should always be 13, but on the first interval, it is 14. it then switches back to 13 until the second it up. This is showing the user 14 for a split second and then shows 13 until the second is done.
Once the timer reaches 12, the first to intervals of each second is 14, then 13, and then goes to 12 for the remainder of the second.
What could be causing this? I have debugged this code but can't figure out why it is doing it. I know it is erroring on the var countDownDate = new Date().getTime() + 15 * 60 * 1000; line, but I don't know why. Below is my code.
var temp; var idleTime = 0; var idleInterval; var time: number; $(document).ready(function () { $(this).mousemove(function (e) { idleTime = 0; }); $(this).keypress(function (e) { idleTime = 0; }); idleInterval = setInterval(timerIncrement, 60000); // 1 minute if (document.querySelector("#IdleTimeout") != null) { time = (+document.querySelector("#IdleTimeout").getAttribute("value") - 1); } }); function timerIncrement() { idleTime = idleTime + 1; if (time != null) { if (idleTime > time) { SetUpTimer(); } } } function pad(num, size) { num = num.toString(); while (num.length < size) num = "0" + num; return num; } function SetUpTimer() { if (document.getElementById('TimeOutModal') != null) { var countDownDate = new Date().getTime() + 15 * 60 * 1000; $('#TimeOutModal').modal('show'); temp = setInterval(function () { var now = new Date().getTime(), timel = countDownDate - now; var minutes = Math.floor((timel % (1000 * 60 * 60)) / (1000 * 60)), seconds = Math.floor((timel % (1000 * 60)) / 1000); document.getElementById("logout-counter-span").innerHTML = pad(minutes, 2) + ":" + pad(seconds, 2); if (timel <= 0) { document.getElementById("timeOutText").innerHTML = "Logging out."; $.ajax({ async: true, type: 'GET', url: `/Logout`, data: null, cache: false, success: (res: any): any => { clearTimeout(temp); clearTimeout(idleInterval); location.href = '/login/'; } }); } }, 300); } else { clearTimeout(temp); clearTimeout(idleInterval); } } $('#TimeOutSignOut').on('click', function () { $.ajax({ async: true, type: 'GET', url: `/Logout`, data: null, cache: false, success: (res: any): any => { clearTimeout(temp); clearTimeout(idleInterval); location.href = '/login/' } }); }); $('#TimeOutSignIn').on('click', function () { $.ajax({ async: true, type: 'POST', url: `/Reset`, data: null, cache: false, success: function (res: any) { try { clearTimeout(temp); clearTimeout(idleInterval); idleInterval = setInterval(timerIncrement, 60000); // 1 minute } catch (e) { //console.log(e); } } }); });
var time = 60; <input data-val="@time" id="IdleTimeout" type="hidden" value="@time"> <div class="modal fade" id="TimeOutModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalCenterTitle" aria-hidden="true" data-backdrop="static" data-keyboard="false"> <div class="modal-dialog modal-dialog-centered" role="document"> <div class="modal-content"> <div class="modal-body"> <p id="timeOutText"> Your session is about to expire. You will be automatically signed out in <span id="logout-counter-span" class="bold"></span> </p> </div> <div class="modal-footer"> <a id="TimeOutSignOut" type="button" class="btn btn-secondary mr-2">Sign-out</a> <a id="TimeOutSignIn" type="button" class="btn btn-primary" data-dismiss="modal">Keep me logged in</a> </div> </div> </div> </div>
Monday, January 25, 2021 5:35 PM
Answers
-
User1535942433 posted
Hi MarcusAtMars,
Accroding to your description and codes,I have created a test and I reproduced your problems.
As far as I think,your problem is that it will refresh for every 1 minute. I suggest you could set a flag.When you do the idle timer,the flag is true.And the page will not be refreshed.
Just like this:
<script> var temp; var idleTime = 0; var idleInterval; var time = 5; var flag = false; $(document).ready(function () { $(this).mousemove(function (e) { idleTime = 0; }); $(this).keypress(function (e) { idleTime = 0; }); idleInterval = setInterval(timerIncrement, 10000); // 1 minute if (document.querySelector("#IdleTimeout") != null) { time = (+document.querySelector("#IdleTimeout").getAttribute("value") - 1); } }); function timerIncrement() { if (!flag) { idleTime = idleTime + 1; if (time != null) { if (idleTime > time) { SetUpTimer(); } } } } function pad(num, size) { num = num.toString(); while (num.length < size) num = "0" + num; return num; } function SetUpTimer() { flag = true; if (document.getElementById('TimeOutModal') != null) { var countDownDate = new Date().getTime() + 14 * 60 * 1000; $('#TimeOutModal').modal('show'); temp = setInterval(function () { var now = new Date().getTime(), timel = countDownDate - now; var minutes = Math.floor((timel % (1000 * 60 * 60)) / (1000 * 60)), seconds = Math.floor((timel % (1000 * 60)) / 1000); document.getElementById("logout-counter-span").innerHTML = pad(minutes, 2) + ":" + pad(seconds, 2); if (timel <= 0) { document.getElementById("timeOutText").innerHTML = "Logging out."; flag == false; $.ajax({ async: true, type: 'GET', url: `/Logout`, data: null, cache: false, success: function (res) { clearTimeout(temp); clearTimeout(idleInterval); location.href = '/login/'; } }); } }, 300); } else { clearTimeout(temp); clearTimeout(idleInterval); } } $('#TimeOutSignOut').on('click', function () { $.ajax({ async: true, type: 'GET', url: `/Logout`, data: null, cache: false, success: function (res) { clearTimeout(temp); clearTimeout(idleInterval); location.href = '/login/' } }); }); $('#TimeOutSignIn').on('click', function () { $.ajax({ async: true, type: 'POST', url: `/Reset`, data: null, cache: false, success: function (res) { try { clearTimeout(temp); clearTimeout(idleInterval); idleInterval = setInterval(timerIncrement, 6000); // 1 minute } catch (e) { //console.log(e); } } }); }); </script>
Best regards,
Yijing Sun
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Tuesday, January 26, 2021 8:50 AM -
User-462241089 posted
Thanks, Yij. I also found this to be the solution, too.
function timerIncrement() { idleTime = idleTime + 1; if (time != null) { if (idleTime > time) { clearTimeout(temp); clearTimeout(idleInterval); SetUpTimer(); } } }
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Tuesday, January 26, 2021 8:57 PM
All replies
-
User1535942433 posted
Hi MarcusAtMars,
Accroding to your description and codes,I have created a test and I reproduced your problems.
As far as I think,your problem is that it will refresh for every 1 minute. I suggest you could set a flag.When you do the idle timer,the flag is true.And the page will not be refreshed.
Just like this:
<script> var temp; var idleTime = 0; var idleInterval; var time = 5; var flag = false; $(document).ready(function () { $(this).mousemove(function (e) { idleTime = 0; }); $(this).keypress(function (e) { idleTime = 0; }); idleInterval = setInterval(timerIncrement, 10000); // 1 minute if (document.querySelector("#IdleTimeout") != null) { time = (+document.querySelector("#IdleTimeout").getAttribute("value") - 1); } }); function timerIncrement() { if (!flag) { idleTime = idleTime + 1; if (time != null) { if (idleTime > time) { SetUpTimer(); } } } } function pad(num, size) { num = num.toString(); while (num.length < size) num = "0" + num; return num; } function SetUpTimer() { flag = true; if (document.getElementById('TimeOutModal') != null) { var countDownDate = new Date().getTime() + 14 * 60 * 1000; $('#TimeOutModal').modal('show'); temp = setInterval(function () { var now = new Date().getTime(), timel = countDownDate - now; var minutes = Math.floor((timel % (1000 * 60 * 60)) / (1000 * 60)), seconds = Math.floor((timel % (1000 * 60)) / 1000); document.getElementById("logout-counter-span").innerHTML = pad(minutes, 2) + ":" + pad(seconds, 2); if (timel <= 0) { document.getElementById("timeOutText").innerHTML = "Logging out."; flag == false; $.ajax({ async: true, type: 'GET', url: `/Logout`, data: null, cache: false, success: function (res) { clearTimeout(temp); clearTimeout(idleInterval); location.href = '/login/'; } }); } }, 300); } else { clearTimeout(temp); clearTimeout(idleInterval); } } $('#TimeOutSignOut').on('click', function () { $.ajax({ async: true, type: 'GET', url: `/Logout`, data: null, cache: false, success: function (res) { clearTimeout(temp); clearTimeout(idleInterval); location.href = '/login/' } }); }); $('#TimeOutSignIn').on('click', function () { $.ajax({ async: true, type: 'POST', url: `/Reset`, data: null, cache: false, success: function (res) { try { clearTimeout(temp); clearTimeout(idleInterval); idleInterval = setInterval(timerIncrement, 6000); // 1 minute } catch (e) { //console.log(e); } } }); }); </script>
Best regards,
Yijing Sun
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Tuesday, January 26, 2021 8:50 AM -
User-462241089 posted
Thanks, Yij. I also found this to be the solution, too.
function timerIncrement() { idleTime = idleTime + 1; if (time != null) { if (idleTime > time) { clearTimeout(temp); clearTimeout(idleInterval); SetUpTimer(); } } }
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Tuesday, January 26, 2021 8:57 PM