# Skin/theme swap

Theme-swap functionality will be done via a better-looking <div> at the top of the page, but for right now, it's just thrown on the button. The theme preference should persist through page refreshes through the use of cookies.

I'm going to do five different themes, each in two different sizes, since the site is very bad in 800x600 and still quite bad in 1024x768.

Let me know if it breaks or simply doesn't work. I've noticed a bug that happens once in a blue moon, but I think that's because the browser might be doing parallel work and one script gets too far ahead of the other. I'll have to research it more, but I think it's good enough right now to ask for opinions.

The page will eventually display via <noscript> for those that don't have JavaScript turned on but for right now, it'll just display a message that says:

How it works:

1. Non-JavaScript page is displayed with <noscript>
3. JavaScript then applies the preferred theme via AJAX fetching the appropriate theme (skin[x].html) and the content of the page ([page_name.html]).

The code isn't perfect yet, and I'll definitely have to remove the use of another person's image as the background for the second skin, but it's almost done. About half of the code deals with merely re-positioning the elements when the window is resized. For the sake of brevity, some code is not shown. I apologize for its length.

### index.html:

<script type="text/javascript">
window.onresize = function() { setContentPositions(); setJSMenuPositions(); }
$('html').addClass('js'); </script> <script type="text/javascript">$().ready(function() {

getThemeInfo();

});

if (themeSelect>1) { themeSwapNoInc();}

});
</script>


### funcs.js:

function getThemeInfo()
{
}

function themeSwap()
{
themeSelect++;
if (themeSelect>2 || themeSelect<1) {themeSelect=1;}
$('html').addClass('js'); switch(themeSelect) { case 1: AJAX_LoadResponseIntoElement("mybody", "skin1.txt", function() { AJAX_LoadResponseIntoElement("contentdiv", "index.txt", initPage); }); document.body.style.backgroundImage="url(http://www.solarcoordinates.com/images/bg2b.png)"; document.body.style.backgroundRepeat="repeat-x"; break; case 2: AJAX_LoadResponseIntoElement("mybody", "skin2.txt", function() { AJAX_LoadResponseIntoElement("contentdiv", "index.txt", initPage); }); document.body.style.backgroundImage="url(http://www.constantcollide.com/wp-content/themes/killerbrown/images/texture.jpg)"; document.body.style.backgroundRepeat="repeat"; break; } setCookie("themeSelection",themeSelect,365); } function themeSwapNoInc() { themeSelect--; themeSwap(); } function initPage() {$('#vertnav .kwicks').kwicks({
defaultKwick:0,
max : 205,
spacing : 3,
isVertical : true
});

setContentPositions();
showContainer();

}

function showContainer()
{
$('html').removeClass('js'); } function AJAX_LoadResponseIntoElement (elementId, fetchFileName, cfunc) { var XMLHRObj; if (window.XMLHttpRequest) { XMLHRObj=new XMLHttpRequest(); } else { XMLHRObj=new ActiveXObject("Microsoft.XMLHTTP"); } XMLHRObj.onreadystatechange=function() { if (XMLHRObj.readyState==4 && XMLHRObj.status==200) { document.getElementById(elementId).innerHTML=XMLHRObj.responseText; cfunc(); } } XMLHRObj.open("GET",fetchFileName,true); XMLHRObj.send(); } function findLeft(obj) { var curleft = 0; if (obj.offsetParent) { do {curleft += obj.offsetLeft;} while (obj = obj.offsetParent);} else { curleft += obj.offsetLeft; } return curleft; } function findTop(obj) { var curtop = 0; if (obj.offsetParent) { do {curtop += obj.offsetTop;} while (obj = obj.offsetParent);} else { curtop += obj.offsetTop; } return curtop; } function findmyparent(e) { var srcElement = e.srcElement ? e.srcElement : e.target; if (srcElement.className.search("jsmenu")==-1 && srcElement.className.search("kwick")==-1 && srcElement.className!="vertnav" && srcElement.className!="active") { document.getElementById("jsmenu" + lastindex).style.display="none"; submenuvisible=false; } } function getContentHeight() { return window.innerHeight; } function getContentWidth() { return window.innerWidth; } function setContentPositions() { var DOMheight = getContentHeight()? getContentHeight(): window.document.body.parentElement.clientHeight; var DOMwidth = getContentWidth()? getContentWidth(): window.document.body.parentElement.clientWidth; var y_lbound, x_lbound, x_ubound; var container_ymod, container_ymin; var container_xmod, container_xmax, container_xmin; var content_xmod, content_xmax, content_xmin; switch (themeSelect) { case 1: y_lbound=727; x_lbound=910; x_ubound=1400; container_ymod=-240; container_ymin=487; container_xmod=-240; container_xmax=1160; container_xmin=670; content_xmod=-490; content_xmax=910; content_xmin=420; break; case 2: y_lbound=710; x_lbound=910; x_ubound=1400; container_ymod=-178; container_ymin=532; container_xmod=-300; container_xmax=1100; container_xmin=610; content_xmod=-350; content_xmax=1050; content_xmin=560; break; default: } // end switch if (DOMheight > y_lbound) { document.getElementById('containerdiv').style.height = (DOMheight+container_ymod) + 'px'; } else { document.getElementById('containerdiv').style.height = container_ymin + 'px'; } if (DOMwidth > x_lbound) { if (DOMwidth < x_ubound) { document.getElementById('containerdiv').style.width = (DOMwidth+container_xmod) + 'px'; document.getElementById('contentdiv').style.width = (DOMwidth+content_xmod) + 'px'; } else { document.getElementById('containerdiv').style.width = container_xmax +'px'; document.getElementById('contentdiv').style.width = content_xmax + 'px'; } } else { document.getElementById('containerdiv').style.width = container_xmin + 'px'; document.getElementById('contentdiv').style.width = content_xmin + 'px'; } }  ### jsmenucontent.js: function setJSMenuPositions() { var popupleft = findLeft(document.getElementById('kwick1'))+168; var popuptop = findTop(document.getElementById('kwick1')); document.getElementById('jsmenu0').style.left = popupleft + "px"; document.getElementById('jsmenu0').style.top = popuptop -12+ "px"; document.getElementById('jsmenu1').style.left = popupleft + "px"; document.getElementById('jsmenu1').style.top = popuptop +33+ "px"; document.getElementById('jsmenu2').style.left = popupleft + "px"; document.getElementById('jsmenu2').style.top = popuptop +77+ "px"; }  • You use jQuery for the DOM but then don't use it to handle ajax in a cross-browser compliant manner for you? I would use $.ajax rather then messing with XMLHRObj manually. If your going to bother including jQuery then you might aswell use it more. It makes your life easier. Jan 29, 2011 at 13:26
• @Micheal - There's several discussions about that on meta. :P. And in addition to what Raynos mentioned, you should try out a jQuery plugin (electrictoolbox.com/jquery-cookies) for handling cookies. Jan 29, 2011 at 18:13
• Have you read alistapart.com/articles/bodyswitchers? Without going too much details, your method is over-engineered, you should be using jQuery properly (and update it - the version you're using is 3 major versions behind!) and you should try not to copy code from W3Schools. Feb 2, 2011 at 2:47
• No, I haven't read the article... I will, though, thanks for the link. I'm assuming that, by "over-engineered," you mean that I did too much myself and could've used more jQuery. I guess I won't know what you mean until I read the article... which I'll do later tonight. Feb 2, 2011 at 3:33
• RE W3S: I read their articles for reference at times (along with others,) but with the exception of the AJAX fetch function, no code here, to my knowledge, has anything in common with any code found on W3S. The AJAX fetch function has slight differences, but is nonetheless rather similar to what is found on W3S. It's also similar to almost every AJAX fetch function ever posted on the internet (that I've seen, at any rate... I've looked over about 30 examples) so I don't see that as a problem(?). Feb 2, 2011 at 3:35

This may just be me nit picking.

But using this approach I can see getting very very messy. If you decide to have say 40 theme's. That's a heck of a lot of javascript! and especially if you decide that you are going to support things like mobile or tablet.

You are changing the look of your page using javascript. You would be better off in my opinion to have:

<link rel="stylesheet" href="..\css\themes\th1.css" id="themesheet" type="text/css" />


<select id="theme">
<option value="th1" selected="selected">Theme One</option>
<option value="th2">Theme Two</option>
</select>


$('#theme').change(function(){ var link = '..\css\themes\{name}.css'; link = link.replace('{name}',$(this).val());