PDA

View Full Version : Style Sheet Switcher - version 1.1b?



jmar
04-20-2007, 11:35 PM
This is a great script! Very clever, thanks a lot DD. I've been playing with it for a couple of years and having fun with it.

PROBLEM:
There is a small issue that may be a problem for some. I loaded my site in two separate browser windows, both of them were microsoft internet explorer 7. IE6 also had the same problem but firefox worked fine.

1. I set the style in the first browser, and it switched!
2. I reloaded the page in the second browser, and it had the new style!
3. I changed the style in the second browser, and it switched!
4. I reloaded the page in the first browser, and it had the new style!
5. I changed the style in the first browser, and it WOULD NOT CHANGE!!

After much investigation I noticed that the first browser has "www" in the domain and the second browser did not.

The script will read from either (with or without www) but will only write to the specific domain or subdomain that it was called from.

This was a problem because I've hard-coded www's into my url whenever needed, but the user may not type it into the browser. So, there is a good probability that they will end up bouncing from www.domain to just domain.


SOLUTION:
Luckily, cookies have a few more options built-in that were not being used by the script. They were easy to implement and seem to fix the problem.

The extra options are for: path, domain, and secure. I haven't looked into the "secure" setting but I added it anyway. As far as "path" and "domain" go, this is very useful. "Path" can be used to set a cookie for just a subfolder, and "domain" can be used to set the cookie on a subdomain (and fix the problem I was having). NOTE: "domain" will not actually change the domain your cookie is for, only the subdomain!

For anyone who is interested, here is my new styleswitch.js code:





///////////////////////////////////////////////////////
// Style Sheet Switcher version 1.1 Oct 10th, 2006
// Author: Dynamic Drive: http://www.dynamicdrive.com
// Usage terms: http://www.dynamicdrive.com/notice.htm
///////////////////////////////////////////////////////

// ver 1.1b bugfix for domain problem
// JM 04/20/2007
// http://www.jackmarvin.com/


// Select "manual" or "random"
var manual_or_random="manual";

// How often to switch random style?
// "eachtime", "sessiononly", or "x days (replace x with desired integer)"
// Only applicable if mode is random
var randomsetting="7 days";

// Name your cookie
var cookiename = "stylecookie";

// Cookie path
var cookiepath = "/";

// Cookie domain or subdomain
var cookiedomain = ".domain.com";

// Cookie secure
var cookiesecure = "";


///////////////////////////////////////////////////////


// Script logic
if (manual_or_random=="manual"){
var selectedtitle=getCookie(cookiename);
// Load user chosen style sheet from cookie if there is one stored
if (document.getElementById && selectedtitle!=null) {
setStylesheet(selectedtitle);
}
} else if (manual_or_random=="random"){
if (randomsetting=="eachtime") {
setStylesheet("", "random");
// If "sessiononly" setting
} else if (randomsetting=="sessiononly"){
// If "mysheet_s" session cookie is empty
if (getCookie("mysheet_s")==null) {
// Activate random alt stylesheet while remembering its "title" value
document.cookie="mysheet_s="+setStylesheet("", "random")+"; path=/";
} else {
// Just activate random alt stylesheet stored in cookie
setStylesheet(getCookie("mysheet_s"));
}
// If "x days" setting
} else if (randomsetting.search(/^[1-9]+ days/i)!=-1){
// If "mysheet_r" cookie is empty or admin has changed number of days to persist in "x days" variable
if (getCookie("mysheet_r")==null || parseInt(getCookie("mysheet_r_days"))!=parseInt(randomsetting)){
// Activate random alt stylesheet while remembering its "title" value
setCookie("mysheet_r", setStylesheet("", "random"), parseInt(randomsetting));
// Also remember the number of days to persist per the "x days" variable
setCookie("mysheet_r_days", randomsetting, parseInt(randomsetting));
}
} else {
// Just activate random alt stylesheet stored in cookie
setStylesheet(getCookie("mysheet_r"));
}
}


// Main stylesheet switcher function.
// Second parameter if defined causes a random alternate stylesheet (including none) to be enabled
function setStylesheet(title, randomize){
var i, cacheobj, altsheets=[""];
for(i=0; (cacheobj=document.getElementsByTagName("link")[i]); i++) {
if(cacheobj.getAttribute("rel").toLowerCase()=="alternate stylesheet" && cacheobj.getAttribute("title")) {
// If this is an alternate stylesheet with title
cacheobj.disabled = true;
// Store reference to alt stylesheets inside array
altsheets.push(cacheobj);
// Enable alternate stylesheet with title that matches parameter
if(cacheobj.getAttribute("title") == title) {
// Enable chosen style sheet
cacheobj.disabled = false;
}
}
}
if (typeof randomize!="undefined"){
// If second paramter is defined, randomly enable an alt style sheet (includes non)
var randomnumber=Math.floor(Math.random()*altsheets.length)
altsheets[randomnumber].disabled=false;
}
// If in "random" mode, return "title" of randomly enabled alt stylesheet
return (typeof randomize!="undefined" && altsheets[randomnumber]!="")? altsheets[randomnumber].getAttribute("title") : "";
}


// Get cookie
function getCookie(Name) {
// Construct RE to search for target name/value pair
var re=new RegExp(Name+"=[^;]+", "i");
// If cookie found
if (document.cookie.match(re)) {
// Return its value
return document.cookie.match(re)[0].split("=")[1];
}
return null;
}


// Set cookie
function setCookie(name, value, days, path, domain, secure) { // JM 04/20/2007
var expireDate = new Date()
// Set "expstring" to either future or past date, to set or delete cookie, respectively
var expstring = (typeof days!="undefined")? expireDate.setDate(expireDate.getDate()+parseInt(days)) : expireDate.setDate(expireDate.getDate()-5);

//document.cookie = name+"="+value+"; expires="+expireDate.toGMTString()+"; path=/";
document.cookie = // JM 04/20/2007
name+"="+escape(value)+
(days ? "; expires="+expireDate.toGMTString() : "")+
(path ? "; path=" +path : "")+
(domain ? "; domain=" +domain : "")+
(secure ? "; secure" : "");
}


// Interface function to switch style sheets plus save "title" attr of selected stylesheet to cookie
function chooseStyle(styletitle, days){
if (document.getElementById){
setStylesheet(styletitle);
//setCookie("lpstyle", styletitle, days);
setCookie(cookiename, styletitle, days, cookiepath, cookiedomain, cookiesecure); // JM 04/20/2007
}
}


// Delete cookie
function deleteCookie(name){
setCookie(name, "moot");
}


// Optional function that shows which style sheet is currently selected within group of radio buttons or select menu
function indicateSelected(element){
// If element is a radio button or select menu
if (selectedtitle!=null && (element.type==undefined || element.type=="select-one")){
var element=(element.type=="select-one") ? element.options : element;
for (var i=0; i<element.length; i++) {
// If match found between form element value and cookie value
if (element[i].value==selectedtitle){
// If this is a select menu
if (element[i].tagName=="OPTION") {
element[i].selected=true;
} else {
// Else if it's a radio button
element[i].checked=true;
}
break;
}
}
}
}

///////////////////////////////////////////////////////



It's called the same way, so you only need to replace the js file and not any of you html. Be sure to include a dot before the cookiedomain if you want it to work across all subdomains.

I'm sorry if someone already covered this and I just wasted space on this forum.

Peace,

jmar
04-21-2007, 01:54 AM
PROBLEM:
Can not delete subdomain cookie or cookie from www.domain


SOLUTION:


// Delete cookie
function deleteCookie(name) {
if (getCookie(name)) {
document.cookie = name + "=" +
( ( cookiepath ) ? "; path=" + cookiepath : "") +
( ( cookiedomain ) ? "; domain=" + cookiedomain : "" ) +
";expires = 01/01/2000 00:00:00";
alert(name + " - Cookie Deleted"); // Show alert
}
}


The original included function doesn't actually delete the cookie anyway. What it does is change the value to something you probably didn't name your stylesheet.

This new function sets the cookie expiration date to the past, which immediately deletes it.


Peace,

jmar
04-21-2007, 01:59 AM
PROBLEM:
Default style was removed in ver 1.1


SOLUTION:
I put it back in.


Here's the changes...



// Script logic
if (manual_or_random=="manual"){

// Load user chosen style sheet from cookie if there is one stored
var selectedtitle = getCookie(cookiename);
if (selectedtitle == null) { // JM 04/20/2007
setStylesheet(defaultstyle);
} else {
setStylesheet(selectedtitle);
}

} else if (manual_or_random=="random"){



Peace,

ddadmin
04-21-2007, 02:11 PM
Thanks for the modifications. I admit I haven't experimented with the "domain" parameter of cookies so far. Are you saying the declaration:


domain=".domain.com"

would get both www.domain.com and domain.com to read from the same cookie? I know officially that adding a dot in front of the domain makes the cookie accessible to sub domains of a domain as well (ie: sub.domain.com), but wasn't sure about the "www" or non issue.

jmar
04-21-2007, 06:35 PM
Well, it's not so much the ".domain.com" declaration as the "document.cookie = blahblah; domain = blahblah;" in the SetCookie function.

I haven't actually tested it across subdomains, but I believe that's why the parameter is available.

I can tell you that with the changes, the script will set the cookie domain to just "domain.com" even if called from "www.domain.com". And then yes, the same cookie will be used by both domains.

Here's a copy of my newer code, all put together:




///////////////////////////////////////////////////////
// Style Sheet Switcher version 1.1 Oct 10th, 2006
// Author: Dynamic Drive: http://www.dynamicdrive.com
// Usage terms: http://www.dynamicdrive.com/notice.htm
///////////////////////////////////////////////////////

// ver 1.1b bugfix for domain problem
// JM 04/20/2007
// http://www.jackmarvin.com/


// Select "manual" or "random"
var manual_or_random = "manual";

// Select default style
var defaultstyle = "themename";

// How often to switch random style?
// "eachtime", "sessiononly", or "x days (replace x with desired integer)"
// Only applicable if mode is random
var randomsetting = "7 days";

// Name your cookie
var cookiename = "stylecookie";

// Cookie path
var cookiepath = "/";

// Cookie domain or subdomain
var cookiedomain = ".domain.com";

// Cookie secure
var cookiesecure = "";


///////////////////////////////////////////////////////


// Script logic
if (manual_or_random=="manual"){

// Load user chosen style sheet from cookie if there is one stored
var selectedtitle = getCookie(cookiename);
if (selectedtitle == null) {
setStylesheet(defaultstyle); // JM 04/20/2007
} else {
setStylesheet(selectedtitle);
}

} else if (manual_or_random=="random"){
if (randomsetting=="eachtime") {
setStylesheet("", "random");
// If "sessiononly" setting
} else if (randomsetting=="sessiononly"){
// If "mysheet_s" session cookie is empty
if (getCookie("mysheet_s")==null) {
// Activate random alt stylesheet while remembering its "title" value
document.cookie="mysheet_s="+setStylesheet("", "random")+"; path=/";
} else {
// Just activate random alt stylesheet stored in cookie
setStylesheet(getCookie("mysheet_s"));
}
// If "x days" setting
} else if (randomsetting.search(/^[1-9]+ days/i)!=-1){
// If "mysheet_r" cookie is empty or admin has changed number of days to persist in "x days" variable
if (getCookie("mysheet_r")==null || parseInt(getCookie("mysheet_r_days"))!=parseInt(randomsetting)){
// Activate random alt stylesheet while remembering its "title" value
setCookie("mysheet_r", setStylesheet("", "random"), parseInt(randomsetting));
// Also remember the number of days to persist per the "x days" variable
setCookie("mysheet_r_days", randomsetting, parseInt(randomsetting));
}
} else {
// Just activate random alt stylesheet stored in cookie
setStylesheet(getCookie("mysheet_r"));
}
}


// Main stylesheet switcher function.
// Second parameter if defined causes a random alternate stylesheet (including none) to be enabled
function setStylesheet(title, randomize){
var i, cacheobj, altsheets=[""];
for(i=0; (cacheobj=document.getElementsByTagName("link")[i]); i++) {
if(cacheobj.getAttribute("rel").toLowerCase()=="alternate stylesheet" && cacheobj.getAttribute("title")) {
// If this is an alternate stylesheet with title
cacheobj.disabled = true;
// Store reference to alt stylesheets inside array
altsheets.push(cacheobj);
// Enable alternate stylesheet with title that matches parameter
if(cacheobj.getAttribute("title") == title) {
// Enable chosen style sheet
cacheobj.disabled = false;
}
}
}
if (typeof randomize!="undefined"){
// If second paramter is defined, randomly enable an alt style sheet (includes non)
var randomnumber=Math.floor(Math.random()*altsheets.length)
altsheets[randomnumber].disabled=false;
}
// If in "random" mode, return "title" of randomly enabled alt stylesheet
return (typeof randomize!="undefined" && altsheets[randomnumber]!="")? altsheets[randomnumber].getAttribute("title") : "";
}


// Get cookie
function getCookie(Name) {
// Construct RE to search for target name/value pair
var re = new RegExp(Name+"=[^;]+", "i");
// If cookie found
if (document.cookie.match(re)) {
// Return its value
return document.cookie.match(re)[0].split("=")[1];
}
return null;
}


// Set cookie
function setCookie(name, value, days, path, domain, secure) { // JM 04/20/2007
var expireDate = new Date()
// Set "expstring" to either future or past date, to set or delete cookie, respectively
var expstring = (typeof days!="undefined")? expireDate.setDate(expireDate.getDate()+parseInt(days)) : expireDate.setDate(expireDate.getDate()-5);

//document.cookie = name+"="+value+"; expires="+expireDate.toGMTString()+"; path=/";
document.cookie = // JM 04/20/2007
name+"="+escape(value)+
(days ? "; expires="+expireDate.toGMTString() : "")+
(path ? "; path=" +path : "")+
(domain ? "; domain=" +domain : "")+
(secure ? "; secure" : "");
}


// Interface function to switch style sheets plus save "title" attr of selected stylesheet to cookie
function chooseStyle(styletitle, days){
if (document.getElementById){
setStylesheet(styletitle);
//setCookie("lpstyle", styletitle, days);
setCookie(cookiename, styletitle, days, cookiepath, cookiedomain, cookiesecure); // JM 04/20/2007
}
}


// Delete cookie
function deleteCookie(name) {
if (getCookie(name)) {
document.cookie = name + "=" +
( ( cookiepath ) ? "; path=" + cookiepath : "") +
( ( cookiedomain ) ? "; domain=" + cookiedomain : "" ) +
";expires = 01/01/2000 00:00:00";
alert(name + " - Cookie Deleted"); // Show alert
}
}


// Optional function that shows which style sheet is currently selected within group of radio buttons or select menu
function indicateSelected(element){
// If element is a radio button or select menu
if (selectedtitle!=null && (element.type==undefined || element.type=="select-one")){
var element=(element.type=="select-one") ? element.options : element;
for (var i=0; i<element.length; i++) {
// If match found between form element value and cookie value
if (element[i].value==selectedtitle){
// If this is a select menu
if (element[i].tagName=="OPTION") {
element[i].selected=true;
} else {
// Else if it's a radio button
element[i].checked=true;
}
break;
}
}
}
}

///////////////////////////////////////////////////////


Thanks again for a really cool script!

Peace,