Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Page 1 of 2 12 LastLast
Results 1 to 15 of 17
  1. #1
    Master Coder
    Join Date
    Feb 2003
    Location
    Ume, Sweden
    Posts
    5,575
    Thanks
    0
    Thanked 83 Times in 74 Posts

    Post Stylesheet Switcher

    Ok, this is an objectified, slightly revised version of my old Theme Switcher script.

    Even though this script is fully functional in all situations I've tried it in (given the basic JS, DOM, CSS compliance demands are fulfilled and cookies accepted), I still want your comments and suggestions on it, including criticism and pointing out weak points.

    It's broken down in three scripts (alternatively one larger file for the entire thing), separation based on functionality of the object enclosed alone.

    (Check out the cookie handler, it might be useful on it's own in other scripts.)

    ~~~~<cookie.js>~~~~
    Code:
    var cookie={  // The Cookie Handler main object
      Get:function(n){  // Function for getting cookies
        var re=new RegExp(n+'=([^;]*);?','gi');  // Create regex for cookies fetching
        var r=re.exec(document.cookie)||[];  // Fetch cookie using regex
        return unescape(r.length>1?r[1]:null)  // Return unescaped cookie
      },
      Set:function(n,v,e,p,d,s){  // Function for setting cookies
        var t=new Date;  // Get current time and date
        if(e)  // If days to expiry is set
          t.setTime(t.getTime()+(e*8.64e7));  // calculate expiry date
        document.cookie=n+'='+escape(v)+'; '+(!e?'':'; expires='+t.toUTCString())+(!p?'':'; path='+p)+(!d?'':'; domain='+d)+(!s?'':'; secure')  // Set cookie
      },
      Del:function(n,p,d){  // Function for deleting cookies
        var t=cookie.Get(n);  // Get cookie
        document.cookie=n+'='+(!p?'':'; path='+p)+(!d?'':'; domain='+d)+'; expires=Thu, 01-Jan-70 00:00:01 GMT';  // Delete cookie
        return t  // Return the deleted cookie
      },
      Sup:function(){  // Function for detecting cookies support
        cookie.Set('c',true);  // Set dummy cookie
        return cookie.Del('c');  // Return whether dummy was written
      }
    };

    ~~~~<event.js>~~~~
    Code:
    var event={  // The Event Handler main object
      Add:function(f){  // Function for adding onload handlers
        event.col[event.col.length]=f;  // Add event handler to collection
        if(typeof window.addEventListener!='undefined')  // If W3C compliant
          window.addEventListener('load',f,false);  // Apply event handler
        else if(!event.ieSet)  // Otherwise, unless already set
          if(typeof document.onreadystatechange!='undefined')  // If supported
            document.onreadystatechange=event.onload;  // Add In event handler handler
        event.ieSet=true;  // Specify that event handler already is set
        return(typeof window.addEventListener!='undefined')  // Return whether W3C compliant
      },
      onload:function(){  // Function for handling multiple onload handlers in IE
        var m=/mac/i.test(navigator.platform);  // Detect whether mac
        if(typeof document.readyState!='undefined')  // If supported
          if(m?document.readyState!='interactive':document.readyState!='complete')  // And not already finished
            return;  // Exit
        for(var i=0,f;(f=(i<event.col.length)?event.col[i]:null);i++)  // For all event handlers
          f();  // Run event handler
        return  // Exit
      },
      ieSet:false,  // Variable to say whether event handler is set or not
      col:[]  // Collection for event handlers
    };
    ~~~~<themeswitch.js>~~~~
    Code:
    var style={  // Theme Switcher main object
      Set:function(t){  // Function for setting active theme
        for(var i in this.col)  // For each existing title
          for(var j=0,f;(f=(j<this.col[i].length)?this.col[i][j]:null);j++)  // And all stylesheets of that title
            f.disabled=i!=t?true:false;  // Set to enabled or disabled depending on whether title matches user input
      },
      Get:function(){ // Function for determining active theme
        for(var i in this.col)  // For each existing title
          if(!this.col[i][0].disabled)  // Unless disabled
            return i;  // Return title
        return this.Pref()  // Otherwise try to determine preferred title
      },
      Pref:function(){  // Function to determine preferred title
        for(var i in this.col)  // For each existing title
          if(!this.col[i][0].disabled)  // Unless disabled
            return i;  // Return title
        return null  // Otherwise return null
      },
      sum:function(){  // Function to collect existing titles into a collection
        var s=document.styleSheets,i=0;  // Set needed variables
        for(var f;(f=(i<s.length)?s[i]:null);i++)  // For each existing stylesheet
          switch(f.title){  //  Read title
            case '':  // If none or blank
              break;  // Exit
            default:  // Otherwise
              switch(typeof this.col[f.title]){  // Read title
              case 'object':  // If exists in collection
                this.col[f.title][this.col[f.title].length]=f;  // Add stylesheet to that title in the collection
                break;  // Exit
              default:  // Otherwise
                this.col[f.title]=[f]  // Add new titla to collection and add stylesheet to that title
            }
          }
      },
      onload:function(){  // Function to send to onload handler
        style.sum();  // Collect titles
        if(cookie.Sup()){  // If cookies support exists
          var c=cookie.Get('style');  // Get preferred theme from cookie
          style.Set(c||style.Pref())  // Otherwise use the author specified
        }
      },
      onunload:function(){  // Function to send to onunload handler
        if(cookie.Sup()){  // If cookies support exists
          var s=style.Get();  // Get active theme
          cookie.Set('style',s,356,'/')  // Write active theme to cookie
        }
      },
      col:{}  // Collection for titles
    };
    
    event.Add(style.onload);  // Add onload handler
    window.onunload=style.onunload;  // Add onunload handler
    ~~~~<HTML Inclusion>~~~~
    Code:
    <!-- Example Containment -->
    <link rel="stylesheet" type="text/css" href="standard.css" />
    <link rel="stylesheet" type="text/css" href="default.css" title="Default" />
    <link rel="alternate stylesheet" type="text/css" href="strange.css" title="Strange" />
    / - - - /
    
    <a href="#" title="none" onclick="window.style.Set(this.title);return false;">Turn off themes</a><br />
    <a href="#" title="Default" onclick="window.style.Set(this.title);return false;">Change to default theme</a><br />
    <a href="#" title="Strange" onclick="window.style.Set(this.title);return false;">Change to strange theme</a><br />
    
    <img src="none.png" title="Turn off themes" onclick="window.style.Set('none');return false;" /><br />
    <img src="default.gif" title="Change to Default theme" onclick="window.style.Set('Default');return false;" /><br />
    <img src="strange.jpeg" title="Change to Strange theme" onclick="window.style.Set('Strange');return false;" /><br />
    The tutorial and full sources for it are available from <http://members.evolt.org/liorean/scr...eswitch-t.html>.
    There are also text files explaining how to use each of the scripts in it inside the zipfile with tutorial and full sources.

    // liorean
    liorean <[lio@wg]>
    Articles: RegEx evolt wsabstract , Named Arguments
    Useful Threads: JavaScript Docs & Refs, FAQ - HTML & CSS Docs, FAQ - XML Doc & Refs
    Moz: JavaScript DOM Interfaces MSDN: JScript DHTML KDE: KJS KHTML Opera: Standards

  • #2
    Regular Coder Skyzyx's Avatar
    Join Date
    Aug 2002
    Location
    Silicon Valley, CA
    Posts
    980
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Looks good... I came across this a few months ago...

    Code:
    /*****************************
    STYLESWAP
    Original "StyleSwitcher" code by Paul Sowden, http://www.idontsmoke.co.uk/ss/
    Modified by Aaron Jones on October 10, 2002
    Modified even more by Skyzyx Genesis...
    *****************************/
    function setSS(zStyleSheet)
    {
    	for(i=0; (a=document.getElementsByTagName("link")[i]); i++)
    	{
    		if(a.getAttribute("rel").indexOf("style") != -1 && a.getAttribute("title"))
    		{
    			a.disabled = true;
    			if(a.getAttribute("title") == zStyleSheet)
    			{
    				a.disabled = false;
    				new cookie('zPresetStyle', zStyleSheet, 365, '/').set();
    			}
    		}
    	}
    }
    
    function keepSS()
    {
    	if (new cookie('zPresetStyle').read()) activeSS(new cookie('zPresetStyle').read());
    	else activeSS('');
    }

    Here's my cookie code, although it could definitely be slimmed down if it's only used for this...
    Code:
    /*****************************
    COOKIE FUNCTIONALITY
    Based on "Night of the Living Cookie" by Bill Dortch (Released to Public Domain)
    (c) 2003, Skyzyx Technologies
    *****************************/
    function cookie(name, value, expires, path, domain, secure)
    {
    	// Passed Values
    	this.name=name;
    	this.value=value;
    	this.expires=expires;
    	this.path=path;
    	this.domain=domain;
    	this.secure=secure;
    
    	// Read cookie
    	this.read=function()
    	{
    		var arg = this.name + "=";
    		var alen = arg.length;
    		var clen = document.cookie.length;
    		var i = 0;
    
    		while (i < clen)
    		{
    			var j = i + alen;
    			if (document.cookie.substring(i, j) == arg)
    			{
    				var endstr = document.cookie.indexOf (";", j);
    				if (endstr == -1) endstr = document.cookie.length;
    				return unescape(document.cookie.substring(j, endstr));
    			}
    			i = document.cookie.indexOf(" ", i) + 1;
    			if (i == 0) break;
    		}
    		return null;
    	}
    
    	// Set cookie
    	this.set=function()
    	{
    		// Store initial value of "this.expires" for re-initialization.
    		expStore=this.expires;
    
    		// Set time to absolute zero.
    		exp = new Date();
    		base = new Date(0);
    		skew = base.getTime();
    		if (skew > 0)  exp.setTime (exp.getTime() - skew);
    		exp.setTime(exp.getTime() + (this.expires*24*60*60*1000));
    		this.expires=exp;
    
    		document.cookie = this.name + "=" + escape (this.value) + 
    				((this.expires) ? "; expires=" + this.expires.toGMTString() : "") + 
    				((this.path) ? "; path=" + this.path : "") + 
    				((this.domain) ? "; domain=" + this.domain : "") + 
    				((this.secure) ? "; secure" : "");
    
    		// Re-initialize
    		this.expires=expStore;
    	}
    
    	// Kill cookie
    	this.kill=function()
    	{
    		document.cookie = this.name + "=" + 
    				((this.path) ? "; path=" + this.path : "") + 
    				((this.domain) ? "; domain=" + this.domain : "") + 
    				"; expires=Thu, 01-Jan-70 00:00:01 GMT";
    	}
    
    	// Change cookie settings.
    	this.changeVal=function(chVal) { this.kill(); this.value=chVal; this.set(); }
    	this.changeExp=function(chExp) { this.kill(); this.expires=chExp; this.set(); }
    	this.changePath=function(chPath) { this.kill(); this.path=chPath; this.set(); }
    	this.changeDomain=function(chDom) { this.kill(); this.domain=chDom; this.set(); }
    	this.changeSecurity=function(chSec) { this.kill(); this.secure=chSec; this.set(); }
    }

    The CSS <link> tags must have the TITLE attribute...
    <link rel="stylesheet" href="default.css" title="Default" />

    You'd add it to the HTML page like this...
    Code:
    <!-- Inside the HEAD tags... -->
    <script language="javascript" type="text/javascript">
    <!--
    keepSS();
    //-->
    </script>
    
    <!-- Inside the BODY somewhere... -->
    <a href="#" onclick="activeSS('Default');">New Stylesheet</a>
    Last edited by Skyzyx; 02-18-2003 at 09:26 AM.

    Creator of SimplePie and Tarzan AWS, co-founder of WarpShare, co-built the Y! Messenger website, usability-focused, and an INFJ personality.

  • #3
    Master Coder
    Join Date
    Feb 2003
    Location
    Ume, Sweden
    Posts
    5,575
    Thanks
    0
    Thanked 83 Times in 74 Posts
    Oh, I know of Paul's style switcher (presented in an article on ALA quite some time ago) I had just written a mechanism that was much less potent when I read his article - and I decided that I would rework my code to be a full switcher. Later, I reworked it again and allowed it to use stylesheets no matter how they are defined, instead of just taking link tags into account.

    Throw in my cookie handler and it was pretty much finished.

    Now, my switcher has some points that Paul's hasn't - it's objectbound, shorter (If you erase all that unnecessary commenting, anyway), and can handle all stylesheets instead of only link tags.
    liorean <[lio@wg]>
    Articles: RegEx evolt wsabstract , Named Arguments
    Useful Threads: JavaScript Docs & Refs, FAQ - HTML & CSS Docs, FAQ - XML Doc & Refs
    Moz: JavaScript DOM Interfaces MSDN: JScript DHTML KDE: KJS KHTML Opera: Standards

  • #4
    Regular Coder Skyzyx's Avatar
    Join Date
    Aug 2002
    Location
    Silicon Valley, CA
    Posts
    980
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Cool!

    Creator of SimplePie and Tarzan AWS, co-founder of WarpShare, co-built the Y! Messenger website, usability-focused, and an INFJ personality.

  • #5
    New Coder
    Join Date
    May 2004
    Location
    Some place called the Earth I think...
    Posts
    99
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Why not just a simple

    Code:
    <script>
    
    function swap-style(theHref) {
    
    document.all.styleSheet.href=theHref;
    }
    </script>
    
    <link rel="stylesheet" id="styleSheet" type="text/css">
    
    <a href="javascript:void;" onclick="swap-style('style.css');">Swap Style 1</a>
    Dont do drugs, get high on life

    13 years and getting nowhere fast.....


    M_Mk

  • #6
    Supreme Master coder! glenngv's Avatar
    Join Date
    Jun 2002
    Location
    Philippines
    Posts
    10,966
    Thanks
    0
    Thanked 236 Times in 233 Posts

    You brought this thread to life only to...

    ...suggest a solution that will only work (if at all) in IE.

  • #7
    Senior Coder joh6nn's Avatar
    Join Date
    Jun 2002
    Location
    72 W. 48' 57" , 41 N. 32' 04"
    Posts
    1,887
    Thanks
    0
    Thanked 1 Time in 1 Post
    that method works just fine, actually ( aside from the point that he's using document.all ). i'm using it on my site.
    bluemood | devedge | devmo | MS Dev Library | WebMonkey | the Guide

    i am a loser geek, crazy with an evil streak,
    yes i do believe there is a violent thing inside of me.

  • #8
    jkd
    jkd is offline
    Senior Coder jkd's Avatar
    Join Date
    May 2002
    Location
    metro DC
    Posts
    3,163
    Thanks
    1
    Thanked 18 Times in 18 Posts
    AFAIK, all others browsers implement UI for switching to alternate stylesheets. The point of using multiple <link/>'s is to provide all of the stylesheets to the browser through markup, then using Javascript for IE to hack a UI. And since you have all these <link/>'s in markup now, it doesn't really matter if you're changing href's or rel's. Probably better to change the rel's because if you're changing the href of a single <link/> element, you may end up with dubious semantics (two links to the same stylesheet, but one with rel="stylesheet" and another to rel="alternate stylesheet").
    Last edited by jkd; 06-17-2004 at 06:41 PM.

  • #9
    Regular Coder oldcrazylegs's Avatar
    Join Date
    Feb 2004
    Location
    East Moline Illinois USA
    Posts
    414
    Thanks
    4
    Thanked 5 Times in 4 Posts

  • #10
    New Coder
    Join Date
    May 2004
    Location
    Some place called the Earth I think...
    Posts
    99
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Quote Originally Posted by joh6nn
    that method works just fine, actually ( aside from the point that he's using document.all ). i'm using it on my site.
    If not document.all, what should I use? Would I go

    getElementById('Stylesheet').href=theStyle;

    ?
    Dont do drugs, get high on life

    13 years and getting nowhere fast.....


    M_Mk

  • #11
    Senior Coder joh6nn's Avatar
    Join Date
    Jun 2002
    Location
    72 W. 48' 57" , 41 N. 32' 04"
    Posts
    1,887
    Thanks
    0
    Thanked 1 Time in 1 Post
    Doom Monkey: that looks about right.

    jkd: you're thinking in the context of alternate-styles provided by the author. i'm thinking in the context of web-site skins defined by the user.

    it did occur to me though that i may have read somewhere that the href attribute isn't supposed to be read/write, but rather read-only. haven't had a chance to look that up and confirm it. the only reason i've been using that method anyway, is because the Dom replaceChild method was crashing Fire Fox. i'll have to check and see if that's fixed in 0.9
    bluemood | devedge | devmo | MS Dev Library | WebMonkey | the Guide

    i am a loser geek, crazy with an evil streak,
    yes i do believe there is a violent thing inside of me.

  • #12
    New Coder
    Join Date
    May 2004
    Location
    Some place called the Earth I think...
    Posts
    99
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Oops, sorry, thats javascript:void(0); on the href of the link, typed too fast i guess

    so it should be change to

    Code:
    <script>
    
    function swapStyle(theHref) {
    
    document.getElementById('styleSheet').href=theHref;
    }
    </script>
    
    <link rel="stylesheet" id="styleSheet" type="text/css">
    
    <a href="javascript:void(0);" onclick="swapStyle('style1.css');">Swap Style 1</a>
    ??
    Last edited by DooM_MonkeY; 06-22-2004 at 08:15 PM.
    Dont do drugs, get high on life

    13 years and getting nowhere fast.....


    M_Mk

  • #13
    Supreme Master coder! glenngv's Avatar
    Join Date
    Jun 2002
    Location
    Philippines
    Posts
    10,966
    Thanks
    0
    Thanked 236 Times in 233 Posts
    It's good that you provide an alternative to Javascript-disabled browsers.
    Code:
    function swapStyle(theHref) {
       if (document.getElementById) document.getElementById('styleSheet').href=theHref;
       else alert('Sorry, not supported.');
       return false; //cancels link action
    }
    If you're using a server-side language:

    <a href="page.php?s=style1.css" onclick="return swapStyle('style1.css');">Swap Style 1</a>

    If none:

    <a href="nojavascriptmsg.htm" onclick="return swapStyle('style1.css');">Swap Style 1</a>

    or

    <a href="#" onclick="return swapStyle('style1.css');">Swap Style 1</a>

  • #14
    New Coder
    Join Date
    May 2004
    Location
    Some place called the Earth I think...
    Posts
    99
    Thanks
    0
    Thanked 0 Times in 0 Posts
    oh so thats what the "return true/false" does, which one does what though?
    Dont do drugs, get high on life

    13 years and getting nowhere fast.....


    M_Mk

  • #15
    Supreme Master coder! glenngv's Avatar
    Join Date
    Jun 2002
    Location
    Philippines
    Posts
    10,966
    Thanks
    0
    Thanked 236 Times in 233 Posts
    If you return false to an event handler, normally the event will be suppressed. Otherwise, it won't.

    Try this:

    <form action="javascript:alert('submitted')" onsubmit="alert('This is an unsubmittable page.');return false">

    <a href="page.htm" onclick="return false;">Unclickable link</a>

    <a href="page.htm" onclick="alert('hello');return true;">The alert will show but the browser will still go to the specified url in href</a>

    <input type="submit" value="Submit" />
    </form>


  •  
    Page 1 of 2 12 LastLast

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •