3
\$\begingroup\$

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:

Please turn JavaScript on!

How it works:

  1. Non-JavaScript page is displayed with <noscript>
  2. If JavaScript is enabled, it loads the theme-preference from cookies.
  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();

AJAX_LoadResponseIntoElement("mybody", "skin1.txt", function() {
  AJAX_LoadResponseIntoElement("contentdiv", "index.txt", initPage);
  });


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

});
</script> 

funcs.js:

function getThemeInfo()
{
themeSelect=checkCookie();
}

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();
replaceCSSMenu();
showContainer();
setJSMenuPositions();

}



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";

}
\$\endgroup\$
  • 4
    \$\begingroup\$ 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. \$\endgroup\$ – Raynos Jan 29 '11 at 13:26
  • 1
    \$\begingroup\$ @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. \$\endgroup\$ – Andrew Jan 29 '11 at 18:13
  • \$\begingroup\$ 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. \$\endgroup\$ – Yi Jiang Feb 2 '11 at 2:47
  • \$\begingroup\$ 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. \$\endgroup\$ – Michael Feb 2 '11 at 3:33
  • \$\begingroup\$ 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(?). \$\endgroup\$ – Michael Feb 2 '11 at 3:35
6
\$\begingroup\$

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" /> 

in your html have

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

then in your javascript have

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

This way you are only changing the css sheet instead of coding in the style changes for every theme.

\$\endgroup\$
  • \$\begingroup\$ I'm assuming that you are referring to switch/case portions of themeSwap(). Yes, I plan to redo that, and yes, the theme swaps will be done via CSS replacements. If skin[x].txt is not already 100% CSS-driven, it will be, and then I'll change the themeSwap() function to work via CSS swaps: main.css is going to be changed to "skin1.css" and a swap to skin[x] will replace it with "skin[x].css". And yes, I plan on making a skin for mobile devices as well. Thanks for letting me know that jQuery can do this, though. I'm new to both JS and jQuery and don't yet know what all jQuery can do for me. \$\endgroup\$ – Michael Jan 31 '11 at 5:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.