Main menu:

Site search

July 2006
M T W T F S S
« Jun   Aug »
 12
3456789
10111213141516
17181920212223
24252627282930
31  

Categories

Tags

Blogroll

Improved Style Switching through Dom Scripting

I recently picked up a copy of Professional CSS – aka "the Where’s Durstan book" – somewhat overdue, it should be noted! I was having a read through the chapter regarding style switching and found myself wanting to tweak the code I was looking at. What was wrong with the code/markup? Actually, nothing major, to be honest. The code worked jus’ fine but what niggled me was that while JavaScript was being used to store set the preferred style (and store a cookie to remember that selection), the links on the page that triggered the style switcher code were written in plain ole HTML with onclick event handlers. These days, whenever I see that sort of thing I just want to take them out and replace with an unobtrusive alternative.

So, that’s what I did.

Here, then, is my take on the style switcher doohicky. My aims were as follows:

  • If you changed the (alternate) styles associated with the page, it should not be necessary to also change the switcher links. I thought it would be great if the script automatically found any available alternate styles and created the links accordingly
  • Discoverability – style switcher links may be too subtle (depending on design), so I thought it would be cool if there was an element of prompting, ie, "you’ve been to the page x amount of times – wanna give these alternative styles a try?" (Note – I did think that maybe you should prompt on the first visit but I thought that asking if someone wants to try another style out when they’ve seen the site for the first time was not really giving them time to decide what they do or don’t like about the site).
  • If JavaScript is disabled, the style switcher links should simply not be displayed to the user
  • Finally, I wanted the script to be customizable, such that with a couple of variables you could specify where on the the page the switcher should be inserted.

So, here’s the script (at least my additions) but you really should see it in context. Note: the ¬ character means that the line break is displayed here for formatting reasons only (should not be like this in the actual source code)

/*
This style switcher enhancement was written by Ian Lloyd (http://lloydi.com/).
The basis for this addition comes from Ethan Marcotte\'s style switcher as
documented in the Wrox book professional CSS.

Feel free to use on your site but please leave comment as-is (adding your
own comments regarding further modifications that you may choose to make.
*/

// VARIABLES - uncomment and customise to suit needs
var ContainerID = \"content\"; //Add the name of the container that you ¬
  want the switcher tool to be written into here
var Position = \"first\"; // If you enable this, the switcher will be  ¬
  inserted as either the first item in the parent container, otherwise  ¬
  it\'ll add as last item
var PromptMessage = \"Did you notice that you can change the display of  ¬
  this site using these links above? [This note will not be displayed  ¬
  after you hit refresh or visit another page]\";
var promptTrigger = 20; //how many page views until the prompt to check  ¬
  out the other styles appears;
// End variables

function findCSS() {
//check for previous visits to site/page
var visitCount = readCookie(\"visitCount\");
if ((typeof visitCount==\"undefined\")||(visitCount==\"NaN\")){
 visitCount=0;
 }
else{
 visitCount = parseInt(visitCount);
 visitCount+=1;
 }
//log another visit to the page, store in cookie - to be used for prompt mechanism
setCookie(\"visitCount\", visitCount, 365);

var altCSS = false;//no alternative style sheets found
var CSSlinks = document.getElementsByTagName(\"link\");
if (CSSlinks.length>0)
 {
 var switcherDiv = document.createElement(\"div\");
 switcherDiv.setAttribute(\"id\",\"switcher\");
 var ul = document.createElement(\"ul\");

 //write in link to default style
 var defaultLI = document.createElement(\"li\");
 defaultLI.setAttribute(\"class\",\"first\");
 defaultLI.setAttribute(\"className\",\"first\");
 var defaultLItext = document.createTextNode(\"Default style\");
 var defA = document.createElement(\"a\");
 defA.setAttribute(\"href\",\"#\");
 defA.setAttribute(\"title\",\"default\");
 defA.onclick = doSwitch;
 defA.appendChild(defaultLItext);
 defaultLI.appendChild(defA);
 ul.appendChild(defaultLI);

 //loop through all CSS links - look for alternate styles
 for (i=0;i<CSSlinks.length;i++) {
  if (CSSlinks[i].rel==\"alternate stylesheet\") {
   altCSS = true;//there are alternative style sheets here
   var newLI 		= document.createElement(\"li\");
   var newA		= document.createElement(\"a\");
   newA.setAttribute(\"href\",\"#\");
   newA.setAttribute(\"title\",CSSlinks[i].title);
   newA.onclick = doSwitch;
   var newLItext 	= document.createTextNode(CSSlinks[i].title);
   newA.appendChild(newLItext);
   newLI.appendChild(newA);
   ul.appendChild(newLI);
   }
  }
 if (altCSS) { //alternate stylesheets were found - add to document
  //add navigation list to switcher container
  switcherDiv.appendChild(ul);
  //add prompt text for *this visit only*
  if (typeof promptTrigger!=\'undefined\') {
   if (visitCount==promptTrigger) {
    var promptP = document.createElement(\"p\");
    var promptPtext = document.createTextNode(PromptMessage);
    promptP.setAttribute(\"class\",\"style-switch-prompt\");
    promptP.setAttribute(\"className\",\"style-switch-prompt\");
    promptP.appendChild(promptPtext);
    switcherDiv.appendChild(promptP);
    }
   }
   //what parent container is switcher to go into?
   if (typeof ContainerID!=\'undefined\') {//place in container set in variables
    var container = document.getElementById(ContainerID);
    }
   else {//drop into body of document
    var container = document.getElementsByTagName(\"body\");
    container = container[0];
    }
   //where in parent container should it go?
   if (typeof Position!=\'undefined\') {
    container.insertBefore(switcherDiv, container.firstChild );
    }
   else {
    container.appendChild(switcherDiv);
    }
   }
  }
}
function doSwitch(e) {
activeCSS(this.title);
return false;
}
addEvent(window,\'load\',findCSS, false);

So, that was the idea – have a play, see if it works for you (try disabling javascript, download the .js file yourself, try it out on your own site). Whatever your experiences with this, please do add a comment if you have a suggestion or question.

Comments

Comment from bilbao
Time October 30, 2006 at 10:42 am

bilbao gps