I have a raspberry pi that initiates a garage door close event after a 90s delay. I have been successful in showing the countdown timer dynamically update on a web page but for some reason the countdown is erratic and constantly flickers with lower and then higher numbers.
Clearly I must be refreshing something but needless to say I have spent many hours on forums but to no avail. I am hoping that someone can look at my code and give me some direction.
<?php
$pinInput = trim(shell_exec("gpio read 26"));
$pinOutput = trim(shell_exec("gpio read 2"));
if ($pinInput!=$pinOutput){
echo "Timing for auto reclose...";
?>
<br>
<b><span id="countdown">90</span> Seconds</b>
<script type="text/javascript">
var timer = 90,
el = document.getElementById('countdown');
(function t_minus() {
'use strict';
el.innerHTML = timer--;
if (timer >= 0) {
setTimeout(function () {
t_minus();
}, 1000);
} else {
// do stuff, countdown has finished.
}
}());
</script>
<?php
}
elseif ($pinInput=1)
{
echo "Monitoring input...";
}
else
{
echo "Garage door is closing...";
}
?>
I should also mentioned that the above piece of code is within a file called timing.php. This is called on index.php as follows:
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.0/jquery.min.js"></script>
<script type="text/javascript">
var auto_refresh = setInterval(
function ()
{
$('#Input').load('timing.php');
}, 1000); // refresh every 1000 milliseconds
</script>
So in summary, what I would like is for "Timing for auto recluse..." to remain static if ($pinInput!=$pinOutput) but dynamically shown the countdown from 90s.
First let's look at this code, the last bit in your question:
var auto_refresh = setInterval(
function () {
$('#Input').load('timing.php');
}, 1000); // refresh every 1000 milliseconds
That sets up an interval timer that will load the "timing.php" URL into the page once per second.
Now, here's part of what you say is returned from "timing.php":
var timer = 90,
el = document.getElementById('countdown');
(function t_minus() {
'use strict';
el.innerHTML = timer--;
if (timer >= 0) {
setTimeout(function () {
t_minus();
}, 1000);
} else {
// do stuff, countdown has finished.
}
}());
So when the browser receives the response from "timer.php", jQuery will run that code. That sets up a repeating timer function — essentially the same thing as an interval timer, except that it stops itself after a while).
Now, when that code is reloaded, you don't get new global variables timer and el. The global variables already defined by the last load of "timer.php" will simply have their values overridden. That means that the already-in-process previous timeout sequence will suddenly see timer set back to 90.
It's not clear exactly what it is you intend to do. Perhaps that setInterval() is just superfluous, and all you need to do is just load "timeout.php" once. Or, perhaps when the "timeout.php" code loads, it first needs to wipe out any already-running timeout loops, though that seems odd since those are set up to wind down only after 90 seconds.
Related
After a quick cobbling together of a clock app to test the JavaScript linking ability of my Flask App hosted on Heroku, I'm stumbling on the clock text not immediately filling the .innerHTML of my element.
Javascript:
// This sets our ticker to execute the function once a second.
var myVar = setInterval(function() {
myTimer();
}, 1000);
function myTimer() {
var d = new Date();
document.getElementById("clock").innerHTML = d.toLocaleTimeString();
}
The HTML is very simple, just a small h4 element with the id of "clock". I've tried document.onload as well, but whatever I try, the website loads with an empty element then fills it about one second later.
While I have your attention, why is the standard procedure for setting an interval declaring it as a variable? Is it for later reference in the program? Would it work as a naked setInterval(xxxxx);?
Thank you in advance!
setInterval runs the funtion after a specified delay, if you would like to display time on window load for example, you could call your function once in window.onload. Declaring as a variable is needed if you would like to clear the interval, I added a button as an example.
window.onload = () => {
myTimer();
}
const btnStop = document.getElementById("btn-stop");
btnStop.addEventListener('click', () => {
console.log('stopped');
clearInterval(myInterval);
})
var myInterval = setInterval(function() {
myTimer();
}, 1000);
function myTimer() {
var d = new Date();
document.getElementById("clock").innerHTML = d.toLocaleTimeString();
}
<p id="clock"></p>
<button id="btn-stop">stop</button>
I utilized this resource to structure my code: http://www.w3schools.com/jsref/met_win_clearinterval.asp
var intervalID = setInterval(function(){ ogpeWrapper() }, 10);
function ogpeWrapper() {
$("#breadcrumbWrapper, #leftColWrapper, #rightColWrapper").wrapAll('<div id="colWrapperContainer"></div>');
}(jQuery);
function myStopFunction() {
if (document.getElementById('colWrapperContainer')) {
clearInterval(intervalID);
setIntervalID = undefined;
}
}
My ogpeWrapper function is running, but the clearInterval function is not.
Basically, once $("#breadcrumbWrapper, #leftColWrapper, #rightColWrapper").wrapAll(''); runs, I want the interval to stop running it.
Edit - 12:24pm CST:
This is the base code I utilize to wrap the listed elements -
(function($) {
$("#breadcrumbAds, #breadcrumbWrapper, #containerTopParsys, #leftColWrapper, #rightColWrapper").wrapAll('<div id="colWrapperContainer"></div>');
})(jQuery);
This code works, but it doesn't process the change until after the DOM has completely loaded. I need the function to work as soon as those elementals are all available. So I need to use a setInterval to process the function, then clear the interval once the function is processed.
If anyone knows of another way to do this, besides a setIterval, please let me know.
You need to create a definite if else condition within the variable so you know exactly when it will start and when it will stop. Also, because the minimum millisecond interval timing is not consistent across browsers, although you want it to detect really fast, I would recommend a "safer" number and use 100 as the minimum instead. The .length method is a handy little way for you to check if an element is on a page; You can use it as a pseudo dynamic true/false conditional. Lastly, in your .wrapAll() tag, I swapped your single and double quotes, as it is best practice to do such.
var colWrapper = setInterval(function(){
if ($('div#colWrapperContainer').length > 0) {
var doNothing = "";
clearInterval(colWrapper);
} else {
$("#breadcrumbWrapper, #leftColWrapper, #rightColWrapper").wrapAll("<div id='colWrapperContainer'></div>");
}
}, 100);
Here is a working example for your reference Wrap Example
Update:
Example for putting the script inside the <body> tag (no window.load/document.ready) so that it runs independently as soon as it is loaded.
<script type="text/javascript">//<![CDATA[
//http://stackoverflow.com/questions/33483000/clearinterval-function-not-clearing-setinterval-function/33483267#33483267
//Auto Wrap Solution
//Alexander Dixon [11-02-2015]
var wrapThese = $("#breadcrumbWrapper, #leftColWrapper, #rightColWrapper");
var colWrapper = setInterval(function () {
if ($('div#colWrapperContainer').length > 0) {
var doNothing = "";
clearInterval(colWrapper);
} else {
wrapThese.wrapAll('<div id="colWrapperContainer"></div>').addClass('success');
}
}, 100);
//]]>
</script>
Okay so I don't have much experience with jQuery. What I'm trying to do here is make the background of the page change every 5 seconds (10 seconds actually but 5 is for testing). Along with this I want a countdown animation, like a bar below on the page. I've got the background changing every 5 seconds but I cant get the bar animations working. It only occurs once or twice but then never happens again :////
this is the code for the bar animation
var initialWidth = 0;
var initialHeight = 0;
var firstMeasurements = function(){
initialHeight = $(".countdown").height() + "px";
initialWidth = $(".countdown").width() + "px";
}
$(function(){
var bar = $(".countdown");
function countdown() {
bar.animate({"width":"0px"}, 5000);
}
function restartCountdown() {
bar.css("width", initialWidth);
countdown();
setTimeout(restartCountdown, 5000);
}
bar.css("height", initialHeight);
restartCountdown();
});
"countdown" is the class of the div that I want to animate every 5 seconds.
Can someone please tell me what is wrong with my code?
thank you.
Here is the complete code LIVE DEMO
$(function () {
var firstMeasurements = {
width: $("#countdown").css('width'),
height: $("#countdown").css('width')
}
var startAnim = function () {
$("#countdown").animate({
"width": "0px", "height": "0px"
}, 5000, resetAnim)
}
var resetAnim = function () {
$("#countdown").css({
"width": firstMeasurements.width,
"height": firstMeasurements.height
});
startAnim();
}
startAnim()
});
Here you go... This should be enough to get you started :)
var time = 3000, //3 seconds
var timer = setInterval(function(){
alert("Hello");
}, time);
//Why declare the interval as timer var?
//Because you may wish to cancel it at some point by doing
//clearInterval(timer);
Instead of :
setTimeout(restartCountdown, 5000);
You should use:
setInterval(restartCountdown, 5000);
Because setTimeOut() will fire only once, but setInterval() will always fire every 5 seconds.
Note:
In your case you are calling restartCountDown() recursively, so if you will use setInterval() you need to change your function to the following:
function restartCountdown() {
bar.css("width", initialWidth);
setInterval(countdown, 5000);
}
This way you will initialize the width then fire countdown() after 5 seconds.
Ohoh. The Every-N-seconds question ;)
Actually today you only can use `setTimeInterval``
setInterval(function(){
console.log("5 secs have passed");
}, 5000/*5000 ms=5 seconds*/);
But care ! your Javascript can do nothing else during the setInterval.
Browser javascript runs in a single thread. So if you perform something that takes too long - it will freeze browser.
Future of Javascript will bring multi-thread.
To be able to do things during you wait 5 seconds, I have used strategies like asynchronous request. Well, fell free to ask if you dont want to be frozen during the 5 secs.
Some reads ? http://ejohn.org/blog/how-javascript-timers-work/
I am working on a web based application i.e LMS Learning Management System. In this application a student can read chapters and give test for that chapters. And for reading a chapter a specific time is alotted to the user which is capturing using the timer tick. While reading the chapter, a captcha(i.e developed in aspx page) comes at after every 12 minutes. Now i want when captcha comes on the window while reading, the timer should get paused, and when user submit the captcha timer get resumed from where it left its previous tick. For this i have tried a solution using javascript but it didn't work.
Here is the codr that i have tried
<script type="text/javascript">
function startTimer() {
var timer = $find("<%=Timer1.ClientID%>")
timer._startTimer();
}
function stopTimer() {
var timer = $find("<%=Timer1.ClientID%>")
timer._stopTimer();
}
function showCaptchaOnChapter() {
//stopTimer();
ShowNewPage();
setTimeout('showCaptchaOnChapter()', 120000);
stopTimer();
}
function showRandomQuestionOnChapter() {
ShowChapterQuestion();
setTimeout('showRandomQuestionOnChapter()', 900000);
}
//setTimeout('showCaptchaOnChapter()', 360000);
//setTimeout('showRandomQuestionOnChapter()', 120000);
</script>
The definition for ShowNewPage()
function ShowNewPage() {
var callbackFunctionArray = new Array(CloseCaptchaPopUp);
modalWin.ShowURL('Captcha.aspx', 225, 290, 'Please enter characters dislayed in image to proceed', null, callbackFunctionArray);
}
here in this script i had set Captcha arrival time at 2 minutes so i can test faster. Captcha coming at Regular interval i.e of 2 minutes but timer tick not getting stopped.
How could i do this?
After the time out has occurred show your captcha and initiate other timeout.
function showQuestion() {
updateTimer();
getQuestion();
setTimeout(showCaptcha, time);
}
function showCaptcha() {
getCaptcha();
//some listener for submitting of captcha eg:submitCaptcha
}
function submitCaptcha() {
if captcha===correct
showQuestion();
}
I have a timer script which scrolls up and down and repositions the page to the top every 10 seconds and back down every 5 seconds. My problem is I can't get it to scroll all the way down.
<script language="JavaScript" type="text/javascript">
// Configure refresh interval (in seconds)
var refreshinterval=300
// Shall the coundown be displayed inside your status bar? Say "yes" or "no" below:
var displaycountdown="yes"
var starttime
var nowtime
var reloadseconds=0
var secondssinceloaded=0
function starttime() {
starttime=new Date()
starttime=starttime.getTime()
countdown()
}
function countdown() {
nowtime= new Date()
nowtime=nowtime.getTime()
secondssinceloaded=(nowtime-starttime)/1000
reloadseconds=Math.round(refreshinterval-secondssinceloaded)
if (refreshinterval>=secondssinceloaded) {
var timer=setTimeout("countdown()",1000)
if (displaycountdown=="yes") {
window.status="Page refreshing in "+reloadseconds+ " seconds"
}
if (timer % 5 == 0) {
window.scrollTo(0,1200);
}
if (timer % 10 == 0) {
window.scrollTo(0,0);
}
}
else {
clearTimeout(timer)
window.location.reload(true)
}
}
window.onload=starttime
</script>
How do i get it to scroll all the way down or page down?
thanks in advance
I think this is much simpler and achieves what you're looking for:
function starttime() {
setTimeout('scrollDown()',5000);
}
function scrollDown() {
window.scrollto(0, document.body.scrollHeight);
setTimeout('scrollUp()',5000);
}
function scrollUp() {
window.scrollto(0,0);
setTimeout('scrollDown()',5000);
}
window.onload = starttime
The reason your page wouldn't scroll all the way down is probably with your pixel value of 1200. This scrolls the page down 1200px, which may or may not be all the way. Heck, your page could be 10000px high or more. Try setting a limit that you can safely know you're page will never surpass, like 20000, and it should scroll all the way to the bottom. :D