Changing background image based on local time - javascript

I've been trying to figure this out for over 4 hours, none of the questions (that have already been answered) in stack work for me, here's the code:
<html>
<head>
<style>
.day {
background-image: url(test2.png);
}
.night {
background-image: url(test.png);
}
</style>
</head>
<body class="day" class="night">
<script>
setInterval(function() {
var d = new Date();
var n = d.getHours();
if (n > 23 || n < 6) {
document.body.className = "night";
} else {
document.body.className = "day";
}
console.log("test");
}, 1000 * 60 * 60);
</script>
</body>
</html>
I want the night background to be from 11PM to 7AM, and the rest of the time for the day background.
As you might see, those test.png pictures are changed instead of original so you don't see the pictures I want, since they contain minor gore, feel free to put your own test images in them.

Your logic is perfect and works as intended (I changed the images to colours, because StackOverflow gave an error when I tried your snippet).
The only problem (to you a problem, to others a design feature) is that setInterval starts after the first interval is complete. In other words; you had to wait an hour to see the results.
In my fix I moved the JavaScript to a separate function, which is mentioned by the setInterval and after that immediately called.
I also removed the double classes on the body, because that will be set by the function.
Edit: I forgot to mention that a double class (day and night) can occur with this code. You should write some logic to remove day when night is applied and vice versa.
Edit2: I changed the equation for the time a bit. n can't be bigger than 23, but it can be 23. Also, you wanted to change it to day around 7, which includes 6. So your equation should be right.
As user Salman A states, you should decrease the interval. If a user starts browsing your site at 6:58 and stayed one a single page for an hour (I don't know the business of your website, but that's quite long), the background would change around 7:58. So decrease your interval to something like 1 or 2 minutes (1000 * 60 * 1 or 1000 * 60 * 2).
<html>
<head>
<style>
.day {
background-color: #ccc;
}
.night {
background-color: #333;
}
</style>
</head>
<body>
<script>
setInterval(change_background, 1000 * 60 * 60);
function change_background() {
var d = new Date();
var n = d.getHours();
console.log(n);
if (n == 23 || n < 7) {
document.body.className = "night";
} else {
document.body.className = "day";
}
console.log("test");
}
change_background();
</script>
</body>
</html>

Related

Java Script - How to load frames/images fast?

I've been trying for a while now to make my images play like its a video to get like 2+ fps.
My system updates the jpeg file pretty quick i just need it to load quick, i can't get more than 1 frame per second which is pretty slow, even if i change the loop timeout to less than 1s it won't load or it will take more than 2seconds to load.
My current code :
<?php
?>
<!DOCTYPE html>
<html>
<body>
<style>
.disclaimer{
display: none;
}
</style>
<p id="demo"></p>
<img id="dumb" name="dumb" src="dumb.jpg" alt="Image" style="width:960px;height:540px;">
<script language="JavaScript">
function randomIntFromInterval(min, max) { // min and max included
return Math.floor(Math.random() * (max - min + 1) + min)
}
window.setInterval(function() {
var myImageElement = document.getElementById('dumb');
var d = new Date();
myImageElement.src = 'dumb.jpg?ver=' + d.getTime();;
}, 1000);
</script>
</body>
</html>

How to make setInterval of a progress bar work when a tab is inactive

I can see there are a couple of similar questions asked here but unfortunately I couldn't find the answer I expect.
I am quite new to Programming and trying my hands on Javascript Progress Bar. I have a counter to countdown whenever the progress bar runs out of width but i got the problem, when the tab in focus is inactive, the progress bar pauses thereby keeping counter not to countdown.
I got the idea of using web workers http://www.tutorialspoint.com/html5/html5_web_workers.htm but I couldn't get that to work. I would appreciate any form of help I get here.
Below is my Code.
<!DOCTYPE html>
<html>
<head>
<script
src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/
jquery.min.js">
</script>
<style>
#progressContainer {
position: relative;
width: 97%;
height: 25px;
background-color: #ddd;
margin-bottom: 15px;
}
#progressBar {
position: absolute;
width: 0%;
height: 100%;
background-color: #A9A9A9;
}
#container{
width: 200px;
height: 200px;
border: 1px solid black;
padding: 10px
}
</style>
<script>
$(document).ready(function(){
$("#countDownBtn").click(function(){
var cdNumber = $("#countDownId").val();
var id = setInterval(frame, 100);
var elem = document.getElementById("progressBar");
var progressBarWidth = 101;
function frame() {
if (progressBarWidth === 0) {
clearInterval(id);
cdNumber--;
$("#countDownId").val(cdNumber);
console.log(cdNumber);
if (cdNumber === 0) {
clearInterval(id);
}
else {
elem.style.width = '100%';
progressBarWidth = 100;
//alert("Hi");
}
}
else {
progressBarWidth--;
elem.style.width = progressBarWidth + '%';
}
}
});
});
</script>
</head>
<body>
<div id="container">
<div>
<input type="text" id="countDownId" value="">
<button id="countDownBtn" class="btn">Click</button>
</div><br>
<div id="progressContainer">
<div id="progressBar"></div>
</div>
</div>
</body>
You'll always run into such problems when depending on the precision of some interval; even requestAnimationFrame. They ain't precise.
The better approach (not just in this case, but pretty much every time you have to transition a value over time) is to save the startTime and compute the passed time in the interval (as #Nosyara already suggested).
When dealing with scaling-factors and/or pausing of this stuff, things can get messy again. Here a utility for this task:
// The basic concept of this "Clock" is a linear equation over Date.now()
// plus the logic to make this equation pausable.
// therefore it's completely independant of **any** interval; it's just math.
function Clock(v){
var p=true,m=1,b=+v||0,n=Clock.now;
return Object.assign(Object.create(Clock.prototype),{
// getter() / setter(value)
// I don't use real getter and setter, because this syntax
// allows/implements method-chaining
value(v){return arguments.length?(b=(+v||0)-(!p&&m*n()),this):b+(!p&&m*n())},
speed(v){return arguments.length?(v=+v||0,p||v===m||(b+=n()*(m-v)),m=v,this):m},
paused(v){return arguments.length?(((v=!!v)===p)||(b+=n()*((p=v)?m:-m)),this):p},
});
}
Object.assign(Clock.prototype,{
valueOf(){return this.value()},
//aliases for setting the paused() state; doesn't matter if you call them repeatedly.
start(){return this.paused(false)},
stop(){return this.paused(true)},
});
Clock.now=Date.now; //the function used for timing
//Clock.now=performance&&performance.now?performance.now.bind(performance):Date.now;
Now to your code:
$(function(){
function frame(){
//yes, countDown get's converted to Number
var value = Math.max(0, countDown);
var count = Math.ceil(value);
var progress = value % 1;
$progressBar.width( progress * 100 + "%" );
//so that I don't update $countDown.val() on every frame, but only if necessary
//on the other hand, it wouldn't be that bad.
if(count !== lastCount) $countDown.val( lastCount = count );
//either stop the countDown or request the next frame.
if(value > 0) requestAnimationFrame(frame);
else countDown.stop();
}
//create a Clock and set speed. Clock is paused by default.
var countDown = Clock().speed( -1 / 10000/*ms*/ );
var $progressBar = $("#progressBar");
var $countDown = $("#countDownId");
var lastCount;
$("#countDownBtn").click(function(){
//if !countDown.paused() then there already is a pending `requestAnimationFrame(frame)`
//from the last call of frame()
if(countDown.paused()) requestAnimationFrame(frame);
countDown.value( $countDown.val() ).start();
});
})
I had similar problems in one of my projects in Chrome browser. The root of problem, that Chrome allows up to 1 timer event per second (setTimeout or setInterval) if tab is not active. In case there more than 1 call per second - it creates queue, than behavior of page depends on logic inside events and may look not as expected. One of solutions is to check visibility of the page and manage intervals Check here
As #ManoDestra pointed out in the comment, you should use requestAnimationFrame instead of setInterval.
The best solution I would propose is utilizing the HTML5 Visibility API to detect when a tab becomes active again after being inactive, and then update the progress bar accordingly. Perhaps you could store the timestamp of the countdown when it is initialized, and when the tab becomes active again, you look at the new timestamp and make a comparison.
You can use setTimeout instead and use recursion. It could look something like this:
var stopInterval = false;
frame();
function frame() {
if(stopInterval) return;
// Your stuff to run in interval HERE
setTimeout(frame, 100);
}
Webworkers are not supported in older browsers. Also browsers specify how they handle setTimeout and setInterval on inactive tab individually, so the behavior may differ. Chrome seems to slow down the recursion alot (1 per second?).
Specifically in your case you can use clock time to represent right progress. When you don't want trust browser about interval events.
Let say you want 10 sec countdown:
var tm = new Date().getTime() + 10000; // 10 sec in milliseconds
setInterval(function(){
var secondsPassed = (tm - new Date().getTime()) / 1000;
// update UI
}, 100); // You can use variable here in different visibility modes

Simple countdown using minutes and seconds

I need a countdown that will refresh a page, and I think I've finally got it, except for one thing. I'd like the countdown to be in minutes and seconds, not just seconds (the countdown is for one hour). A simple MM:SS format would be fine, but also writing out minutes and seconds would work. Can anybody help?
<SCRIPT LANGUAGE="JavaScript">
<!--
var counterobj = document.all ? counter : document.getElementById("counter");
var countdownfrom = 3600; //countdown period in seconds
var currentsecond = counterobj.innerHTML = countdownfrom+1;
function countdown()
{
if (currentsecond!=1)
{
currentsecond-=1;
counterobj.innerHTML = currentsecond;
}
else
{
self.location.reload();
return;
}
setTimeout("countdown()",1000)
}
countdown()
//-->
</script>
Calculate minutes using a floor doing like
minute = Math.floor(currentsecond/60);
Then just output as normal.
edit -- fixed! Hopefully! (accidentally said to use mod -- you need to use Floor, I believe)

Display html content between defined hours mon to friday

i was wondering if there is a quite simple solution to display content between certain hours and only during working days in a Europe timezone?
The hours will be everyday (except weekends) between 9AM and 5PM, between those times a html content should be shown.
If possible a different html content from 5PM till 9AM.
The short version is that you use new Date() to get the current date/time, and then you use DOM manipulation to add/remove that content as appropriate. If you want content to change in-between page loads, you'll probably also want a window.setInterval running to update things constantly.
You might want to check out the Moment.js library (http://momentjs.com/), as it has a number of functions which make working with dates/times easier.
Here's a quickie example (without using Moment) that just checks "are we past 5 or not?":
window.setInterval(function() {
if (new Date().getHours() > 17) { // if it's after 5pm (17:00 military time)
$('#someContent').hide();
} else {
$('#someContent').show();
}
}, 1000 * 60) // this will run every minute
With that hopefully you can figure out how to add the other needed if checks.
Here you go! :)
<html>
<head>
<script type="text/javascript">
var date=new Date();
var year=date.getFullYear();
var month=date.getMonth();
var day=date.getDate(); // fixed
function SetDivContent() {
var div=document.getElementById('date_dependent');
if (year==2010 && month==11) { // fixed (the JavaScript months order is 0-11, not 1-12)
if (day>=3 && day<11) { // the following content will be displayed 12/03/2010, 12/04/2010, [...], 12/09/2010, 12/10/2010
div.innerHTML='content 1';
}
else if (day==11 || day==12) { // this one will be displayed 12/11/2010 and 12/12/2010
div.innerHTML='content 2';
}
else if (day>12) { // this one - 12/13/2010 and later, until the end of December
div.innerHTML='content 3';
}
}
else if (year==2011 && month>=0) div.innerHTML='content 3'; // OPTIONAL - just to ensure that content 3 is displayed even after December.
}
</script>
</head>
<body onload="SetDivContent()">
<div id="date_dependent"></div>
</body>
</html>
answered Nov 30 '10 at 22:16
rhino

Strange problem with JavaScript code

Hi Masters Of Web Development,
first I want to say that I did not believe in my eyes - I've got a piece of javascript that works just fine in IE7, and don't in Firefox!!! :)))) That was little joke. :)
So I already told you the problem (it wasn't joke), now I'm pasting the javascript:
<script type="text/javascript">
<!-- This script and many more are available free online at -->
<!-- The JavaScript Source!! http://javascript.internet.com -->
<!-- Begin
var ms;
ms = %%CONTENT_REFRESH%% - 5;
var stop;
stop = 0;
var myvalue;
function display() {
if (!stop) {
setTimeout("display();", 1000);
}
thetime.value = myvalue;
}
function recalc() {
var hours;
var minutes;
var seconds;
ms = ms - 1;
hours = Math.floor(ms / 3600);
minutes = Math.floor(ms / 60);
if (minutes < 10) {
minutes = "0"+minutes;
}
seconds = ms - (minutes*60) - (hours*3600);
if (seconds < 10) {
seconds = "0"+seconds;
}
myvalue = hours+":"+minutes+":"+seconds;
thetime.value = myvalue;
if (myvalue == "0:00:00") {
stop = 1;
}
if (!stop) {
setTimeout("recalc();", 1000);
}
}
// End -->
</SCRIPT>
This is very old script I know that. It takes my current remaining song time, from my winamp and countdowns in site. But as I said, it does not work in Firefox.
Body and code that calls countdown timer looks like this:
<body class="playlist_body" onLoad="recalc();display();">
Time Left In Song: <INPUT align="center" TYPE="text" Name="thetime" size=5 />
</body>
//Edit: I look at FireBug, and I saw the following error:
thetime is not defined
recalc()playlist.cgi (line 87)
function onload(event) { recalc(); display(); }(load )1 (line 2)
error source line: [Break on this error] thetime.value = myvalue;\n
The problem is that it's accessing DOM elements by name.
Add the following code to the top to declare a variable for the thetime element, add id="thetime" to the INPUT, and add a call to init(); in onload in the body element.
var thetime;
function init() {
thetime = document.getElementById('thetime');
}
By the way, you can replace the textbox with a regular DIV element by setting the div's ID to thetime, and replacing thetime.value with thetime.innerHTML.
Also, it's better to call setTimeout with a function instead of a string; you should replace "display();" and "recalc();" with display and recalc respectively.
IE has a "feature" where an element with a name attribute is placed in the window object, eg.
<div name=foo></div>
Will give you a variable "foo" -- this is non-standard, you should do
document.getElementByName("foo")
To get the timer output element.
var thetime = document.getElementById("thetime");
and add id="thetime" instead of just name="thetime" to the input

Categories