A better night...
Posted in Geek
Well, that was quick! I’ve already been able to fix that transistion problem I described in my previous post.
The problem was that the page could either be displayed in Light Mode or Dark Mode, but it’s default state would be in Light Mode, so if you were viewing in Night Mode, and went to another page, there would be a brief flash as the page initially rendered in Light Mode before receiving the cookie from the browser, and transitioned to Night Mode. I was beginning to find it very annoying, and it also slowed navigating round the site in Night Mode, as you had to wait for the transition to stop before you could work out what was going on.
I guessed the solution to the problem lay in the fact that Night Mode was set after the page was rendered. If I could set it before it was fully rendered, then it would likely render the page as Night Mode when fully parsed. I could then keep the post-render code, and re-use that as a check and/or fallback in case the pre-render code does not worked as planned.
My aim would be to check for the cookie value, and the <body>
tag had been defined, so I went into the main template, and made sure in the header JQuery and JS Cookies were being loaded first, and then right after the <body>
I added some inline Javascript to check for the cookie value, and change the body class accordingly.
<body>
<script language="javascript">
var mode = Cookies.get('night_mode');
if (mode != undefined)
if (mode == "true") {
document.body.className = "night_mode";
}
</script>
[...]
This script would execute before any of the body content would have been parsed, never mind rendered. I tried that and it worked very well! Of course, you want to have a fallback in case it doesn’t work. Another thing I noticed is that I had to set the toggle to it’s Night Mode position from within Javascript after render as it get generated by Bootstrap 4 Toggle. The annoying thing about that it animates it’s position, so you see it start off in “Light” position sliding to “Night” position. I was able to disguise this by setting the opacity of the outside element to transparent, and then fading it in just under a second afterwards, when the sliding animation has completed. There is also a check if the night_mode
class has been set on the body, as a fall-back in case something went wrong in the pre-render code.
function checkDisplayMode() {
var mode = Cookies.get('night_mode');
if (mode != undefined)
if (mode == "true") {
if (!($(body).hasClass('night_mode')))
nightModeOn();
else
$('#night_mode_toggle').bootstrapToggle('on');
}
setTimeout( function() {
$('#mode-toggle-wrapper').animate({
opacity: 1
}, 'slow');
}, 500);
}
It’s a bit of a hack, to be sure, but it works, and if you have Javascript turned off, it’ll default to Light Mode, and the slider toggle (Which wouldn’t work anyway.) does not appear.
Well, when I said “it works”, it works on the desktop browser. It also works on mobile devices, but there’s a couple of formatting issues to sort out…