PDA

View Full Version : Change main header background picture depending on time of day...



simonf
10-05-2017, 10:29 AM
Hi

I would like to be able to change my main header background picture, depending on the time of day, I.e

1) Morning 06h00<>10h00
2) Day 10h00<>16h00
3) Dusk 16h00<>19h00
4) Night 19h00<>06h00

In my CSS file I have a line that say :


#header{background-image:url(../../img/steback.jpg);}

But I need to add 3 more imgs and script to make then change per time of day, thanks in advance :o

jscheuer1
10-05-2017, 02:17 PM
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<style type="text/css">
/* set header default bg in a stylesheet by id (This must be the night image - the one that spans the crossover to a new day) */
#header{background-image:url(../../img/steback.jpg); visibility: hidden;}
</style>
</head>
<body>
<div id="header"></div>
<script>
"use strict";
(function(){ // anonymous function wrapper keeps variable and function names out of the global scope
var timespans = [ // use as many timespans as you want, times should be sequential
{bg: "../../img/steback1.jpg", start: '6:00', end: '9:59'}, // {bg: "image", start: 'hour:minute', end: 'hour:minute'}
{bg: "../../img/steback2.jpg", start: '10:00', end: '15:59'},
{bg: "../../img/steback3.jpg", start: '16:00', end: '19:59'}
], c = timespans.length, tsl = c, units = ['Hours', 'Minutes', 'Seconds'], // get timespans length, establish units for 'tomillis' conversion
the_header = document.getElementById('header').style; // reference the header's style
while (--c > -1) {
timespans[c].start += ':00'; timespans[c].end += ':59'; // add seconds to start and end times for more precise processing
(function(c){ //create closure to preload each potential image
var nbg = new Image();
nbg.addEventListener('load', function(){timespans[c].loaded = true;}, false);
nbg.addEventListener('error', function(){timespans[c].error = true;}, false);
nbg.src = timespans[c].bg;
})(c);
}
function tomillis(cdtime){ // converts start and end colon delimited times to milliseconds since 1970/01/01
cdtime = cdtime.split(':');
var d = new Date(), t = -1;
while(++t < 3){ d['set' + units[t]](+cdtime[t]);}
return d.getTime();
}
function waitforload(ts){
if(ts.loaded){
the_header.backgroundImage = 'url(' + ts.bg + ')';
} else if(!ts.error) { // if the background image is still potentially available and hasn't loaded yet, try again
return setTimeout(function(){waitforload(ts);}, 300);
}
the_header.visibility = 'visible';
}
function changeheaderbg(){
var curtime = new Date().getTime(), lim; // current milliseconds since 1970/01/01, var to later hold the current end time
while (++c < tsl) { // check timespan to find a match
if((lim = tomillis(timespans[c].end)) >= curtime && curtime >= tomillis(timespans[c].start)){
waitforload(timespans[c]); // if found, attempt to set header's bg to timespan's bg
break;
} else {lim = null;} // reset lim to false like value
}
c = -1; // reset c for next run through
if(!lim){
the_header.backgroundImage = ''; // no match found, revert to default
the_header.visibility = 'visible';
lim = tomillis(timespans[0].start);
lim += curtime > lim? (24 * 60 * 60 * 1000) : 0;
}
setTimeout(changeheaderbg, lim - curtime + 1500); // run again at one and a half seconds after a new period would start
}
changeheaderbg(); // initial run of the changeheaderbg function
})(); // end anonymous function wrapper
</script>
</body>
</html>

Any questions, just let me know.

simonf
10-06-2017, 07:00 AM
As always John you're amazing, and always help me..... many many thanks as always, and have a great weekend ahead.... :)

jscheuer1
10-06-2017, 12:57 PM
I think I see a problem. I'll let you know.

jscheuer1
10-07-2017, 02:02 PM
Yes there was a problem. I'm fixing it here and in the original:


<!DOCTYPE html>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<style type="text/css">
/* set header default bg in a stylesheet by id (This must be the night image - the one that spans the crossover to a new day) */
#header{background-image:url(../../img/steback.jpg); visibility: hidden;}
</style>
</head>
<body>
<div id="header"></div>
<script>
"use strict";
(function(){ // anonymous function wrapper keeps variable and function names out of the global scope
var timespans = [ // use as many timespans as you want, times should be sequential
{bg: "../../img/steback1.jpg", start: '6:00', end: '9:59'}, // {bg: "image", start: 'hour:minute', end: 'hour:minute'}
{bg: "../../img/steback2.jpg", start: '10:00', end: '15:59'},
{bg: "../../img/steback3.jpg", start: '16:00', end: '19:59'}
], c = timespans.length, tsl = c, units = ['Hours', 'Minutes', 'Seconds'], // get timespans length, establish units for 'tomillis' conversion
the_header = document.getElementById('header').style; // reference the header's style
while (--c > -1) {
timespans[c].start += ':00'; timespans[c].end += ':59'; // add seconds to start and end times for more precise processing
(function(c){ //create closure to preload each potential image
var nbg = new Image();
nbg.addEventListener('load', function(){timespans[c].loaded = true;}, false);
nbg.addEventListener('error', function(){timespans[c].error = true;}, false);
nbg.src = timespans[c].bg;
})(c);
}
function tomillis(cdtime){ // converts start and end colon delimited times to milliseconds since 1970/01/01
cdtime = cdtime.split(':');
var d = new Date(), t = -1;
while(++t < 3){ d['set' + units[t]](+cdtime[t]);}
return d.getTime();
}
function waitforload(ts){
if(ts.loaded){
the_header.backgroundImage = 'url(' + ts.bg + ')';
} else if(!ts.error) { // if the background image is still potentially available and hasn't loaded yet, try again
return setTimeout(function(){waitforload(ts);}, 300);
}
the_header.visibility = 'visible';
}
function changeheaderbg(){
var curtime = new Date().getTime(), lim; // current milliseconds since 1970/01/01, var to later hold the current end time
while (++c < tsl) { // check timespan to find a match
if((lim = tomillis(timespans[c].end)) >= curtime && curtime >= tomillis(timespans[c].start)){
waitforload(timespans[c]); // if found, attempt to set header's bg to timespan's bg
break;
} else {lim = null;} // reset lim to false like value
}
c = -1; // reset c for next run through
if(!lim){
the_header.backgroundImage = ''; // no match found, revert to default
the_header.visibility = 'visible';
lim = tomillis(timespans[0].start);
lim += curtime > lim? (24 * 60 * 60 * 1000) : 0;
}
setTimeout(changeheaderbg, lim - curtime + 1500); // run again at one and a half seconds after a new period would start
}
changeheaderbg(); // initial run of the changeheaderbg function
})(); // end anonymous function wrapper
</script>
</body>
</html>

Additions/changes highlighted - There were logical flaws in what happens when the default is used, both in recognizing that, and accurately setting the timeout for the next check.