Solved

StyleSwitcher doesn't work in IE 6

Posted on 2004-04-29
12
546 Views
Last Modified: 2008-02-01
Hello,

I have used the A List Apart article (http://www.alistapart.com/articles/alternate) to setup up a sitewide styleswitcher scheme to change colors.

The links to change the styles are here: http://www.saneplanet.com/clients/bowman/style.htm

I have the following stylesheets linked:

<link href="style.css" rel="stylesheet" type="text/css" title="default" />
<link href="style_blue.css" rel="stylesheet" type="text/css" title="blue" />
<link href="style_green.css" rel="stylesheet" type="text/css" title="green" />
<link href="style_mutedblue.css" rel="stylesheet" type="text/css" title="mutedblue" />
<link href="style_mutedgreen.css" rel="stylesheet" type="text/css" title="mutedgreen" />

It works fine in Opera. However in IE 6 (I haven't tried other IE versions yet) for some reason the "mutedgreen" style (the last stylesheet linked) is the default style and regardless of which style I choose, it goes back to the mutedgreen style as soon as I go to another page.

What am I doing wrong?

Here's the javascript (which inside the linked scripts.js):

//From here on functions for the styleswitcher:

function setActiveStyleSheet(title) {
  var i, a, main;
  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") == title) a.disabled = false;
    }
  }
}

function getActiveStyleSheet() {
  var i, a;
  for(i=0; (a = document.getElementsByTagName("link")[i]); i++) {
    if(a.getAttribute("rel").indexOf("style") != -1 && a.getAttribute("title") && !a.disabled) return a.getAttribute("title");
  }
  return null;
}

function getPreferredStyleSheet() {
  var i, a;
  for(i=0; (a = document.getElementsByTagName("link")[i]); i++) {
    if(a.getAttribute("rel").indexOf("style") != -1
       && a.getAttribute("rel").indexOf("alt") == -1
       && a.getAttribute("title")
       ) return a.getAttribute("title");
  }
  return null;
}

function createCookie(name,value,days) {
  if (days) {
    var date = new Date();
    date.setTime(date.getTime()+(days*24*60*60*1000));
    var expires = "; expires="+date.toGMTString();
  }
  else expires = "";
  document.cookie = name+"="+value+expires+"; path=/";
}

function readCookie(name) {
  var nameEQ = name + "=";
  var ca = document.cookie.split(';');
  for(var i=0;i < ca.length;i++) {
    var c = ca[i];
    while (c.charAt(0)==' ') c = c.substring(1,c.length);
    if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
  }
  return null;
}

window.onload = function(e) {
  var cookie = readCookie("style");
  var title = cookie ? cookie : getPreferredStyleSheet();
  setActiveStyleSheet(title);
}

window.onunload = function(e) {
  var title = getActiveStyleSheet();
  createCookie("style", title, 365);
}

var cookie = readCookie("style");
var title = cookie ? cookie : getPreferredStyleSheet();
setActiveStyleSheet(title);



//-->
0
Comment
Question by:polaatx
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 4
  • 2
12 Comments
 
LVL 53

Expert Comment

by:COBOLdinosaur
ID: 10953407
The functions look like what is on tha tsite.  However IE is using the last sheet loaded, so I would say that either they are not being fired correctly or IE is ignoring the code.  Looking at the functions is not going to help without seeing the pages where you have put the code.  If you post a link maybe we cna figure out the problem.

Cd&
0
 
LVL 36

Expert Comment

by:Zyloch
ID: 10953688
First of all, Cd& is right: IE will only load the last stylesheet, which is why mutegreen is loading instead of default.

1. Fix this by setting only default's REL attribute to stylesheet and everything else to alternate like this:

<link href="style_blue.css" rel="alternate" type="text/css" title="blue" />
<link href="style_green.css" rel="alternate" type="text/css" title="green" />
<link href="style_mutedblue.css" rel="alternate" type="text/css" title="mutedblue" />
<link href="style_mutedgreen.css" rel="alternate" type="text/css" title="mutedgreen" />
<link href="style.css" rel="stylesheet" type="text/css" title="default" />

2. This would mean your script would have to change:

function setActiveStyleSheet(title) {
  var i, a, main;
  for(i=0; (a = document.getElementsByTagName("link")[i]); i++) {
    if((a.getAttribute("rel").indexOf("style") != -1 || a.getAttribute("rel").indexOf("alt") != -1) && a.getAttribute("title")) {
      a.setAttribute("rel","alternate");
      if(a.getAttribute("title") == title) a.setAttribute("rel","stylesheet");
    }
  }
}

This changes your function and checks if the REL attribute has alternate in it also. Then, instead of disabling it, it uses setAttribute to change the REL attribute between alternate and stylesheet.

3. You script has both an onLoad and a window.onload. This won't work for some stupid reason that the browser makers came up with. Instead, create a new function for instance returnCookie():

function returnCookie() {
  var cookie = readCookie("style");
  var title=cookie ? cookie: getPreferredStyleSheet();setActiveStyleSheet(title)
}

and inside, put your window.onload code. If you ever have to put an onunload inside your <BODY> tags, then do the same for you window.onunloads.

Now, in the <BODY> of ALL your pages, put this code:

<body onLoad="returnCookie();P7_autoHide('flym1','flym2','flym3');P7_Snap('menTrig1','flym1',-1,20);P7_Snap('menTrig2','flym2',-1,20);P7_Snap('menTrig3','flym3',-1,20);">

Now, returnCookie() is called and the page should work. Try it.

--Zyloch
0
 
LVL 36

Expert Comment

by:Zyloch
ID: 10953709
Your JavaScript code would look like this:

//From here on functions for the styleswitcher:

function setActiveStyleSheet(title) {
  var i, a, main;
  for(i=0; (a = document.getElementsByTagName("link")[i]); i++) {
    if((a.getAttribute("rel").indexOf("style") != -1 || a.getAttribute("rel").indexOf("alt") != -1) && a.getAttribute("title")) {
      a.setAttribute("rel","alternate");
      if(a.getAttribute("title") == title) a.setAttribute("rel","stylesheet");
    }
  }
}

function getActiveStyleSheet() {
  var i, a;
  for(i=0; (a = document.getElementsByTagName("link")[i]); i++) {
    if(a.getAttribute("rel").indexOf("style") != -1 && a.getAttribute("title") && !a.disabled) return a.getAttribute("title");
  }
  return null;
}

function getPreferredStyleSheet() {
  var i, a;
  for(i=0; (a = document.getElementsByTagName("link")[i]); i++) {
    if(a.getAttribute("rel").indexOf("style") != -1
       && a.getAttribute("rel").indexOf("alt") == -1
       && a.getAttribute("title")
       ) return a.getAttribute("title");
  }
  return null;
}

function createCookie(name,value,days) {
  if (days) {
    var date = new Date();
    date.setTime(date.getTime()+(days*24*60*60*1000));
    var expires = "; expires="+date.toGMTString();
  }
  else expires = "";
  document.cookie = name+"="+value+expires+"; path=/";
}

function readCookie(name) {
  var nameEQ = name + "=";
  var ca = document.cookie.split(';');
  for(var i=0;i < ca.length;i++) {
    var c = ca[i];
    while (c.charAt(0)==' ') c = c.substring(1,c.length);
    if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
  }
  return null;
}

function returnCookie() {
  var cookie = readCookie("style");
  var title=cookie ? cookie: getPreferredStyleSheet();setActiveStyleSheet(title)
}

window.onunload = function(e) {
  var title = getActiveStyleSheet();
  createCookie("style", title, 365);
}

var cookie = readCookie("style");
var title = cookie ? cookie : getPreferredStyleSheet();
setActiveStyleSheet(title);


~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Note how the window.onload is now gone and replaced by a function. If on your pages you need a <body onunload="something();">, make a function like getTheCookie() or something that has your window.onunload code in it. Then, call it from your page with <body onunload="getTheCookie();something();">.

--Zyloch
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:polaatx
ID: 10954086
COBOLdinosaur, the link is in my original post. Here it is again: http://www.saneplanet.com/clients/bowman/style.htm

Zyloch, Thanks for all the work.  But before I change things, I am wondering if this means the A List Apart article is wrong. The link to that article is handed out by other experts on this discussion board and it is unlikely that their solution just doesn't work in IE and they never bother to tell you that. So I am wondering that perhaps I did something wrong.

Could there be just some typo or something minor in my code that is causing the problem in IE and there might be no need to do all the changes you suggest?
0
 
LVL 36

Accepted Solution

by:
Zyloch earned 500 total points
ID: 10954221
I only changed the code that much because I was experimenting. ALA is not really wrong.

The problem lies in that you cannot have a window.onload in your script file and a <body onload="something();">

The most simple fix for your site is to do this [Note that this assumes that all your pages have the same menu layout.]

In your script.js file, in your window.onload= section, do this:

window.onload=function(e) {
var cookie = readCookie("style");
  var title = cookie ? cookie : getPreferredStyleSheet();
  setActiveStyleSheet(title);
P7_autoHide('flym1','flym2','flym3');P7_Snap('menTrig1','flym1',-1,20);P7_Snap('menTrig2','flym2',-1,20);P7_Snap('menTrig3

','flym3',-1,20);
}

Then, in all your sites, erase the onLoad="" in <body onload="something();"> to make it just <body>

This should fix it.

--Zyloch
0
 
LVL 53

Expert Comment

by:COBOLdinosaur
ID: 10954290
Sorry I missed the link.  It is not just IE it does not work for.  I also fails for Mozilla.  The script file has some other stuff you are doing on the onload.  I suggest you pull all of those out and test with just to styleswitcher code to see if an interactions is the culprit.

Cd&
0
 

Author Comment

by:polaatx
ID: 10962007
Zyloch,

I changed the window.onload section of the script file to this:

window.onload=function(e) {
var cookie = readCookie("style");
  var title = cookie ? cookie : getPreferredStyleSheet();
  setActiveStyleSheet(title);
P7_autoHide('flym1','flym2','flym3');P7_Snap('menTrig1','flym1',-1,20);P7_Snap('menTrig2','flym2',-1,20);P7_Snap('menTrig3

','flym3',-1,20);
}

and changed the body tag to just <body>

However, in IE, the drop downs are opening in the bottom of the page. So apparently, the javascript calls for the dropdowns have to be in body tag. So unless you can think of the solution for that, I think that option is out. Here's the page: http://www.saneplanet.com/clients/bowman/style1.htm

So then I tried your earlier solution, changing the body tag to this <body onLoad="returnCookie();P7_autoHide('flym1','flym2','flym3');P7_Snap('menTrig1','flym1',-1,20);P7_Snap('menTrig2','flym2',-1,20);P7_Snap('menTrig3','flym3',-1,20);">
and the rel attributes of secondary stylesheets to alternate and then changing the js file to accomidate that.

But in IE the drop downs are messed up and the colors aren't changing in Opera. Here's the page: http://www.saneplanet.com/clients/bowman/style2.htm

I think doing this styleswitching is not easy when drop down menus are present. And since this styleswitching is not important to this site I am going to give up on this and try it again with a site that does not use dropdowns.

I appreciate all the work though. Thanks so much. I learned a lot.

Just one question that is really preplexing to me: Why do you think that the drop downs are not opening correctly in IE when using your earlier solution: http://www.saneplanet.com/clients/bowman/style2.htm ? On my screen, they open to the far left of the screen. The body tag is identical to other pages, only that returnCookie(); was added. The js for the drop downs remains identical.
0
 
LVL 36

Expert Comment

by:Zyloch
ID: 10963663
That's funny... I can't use my laptop right now so I can't access Opera or Netscape or Firebird, but I still have IE6. On my IE6, for both pages, the menus are working correctly. What version of IE do you have? What version of Opera?

--Zyloch
0
 

Author Comment

by:polaatx
ID: 10963762
I am using IE 6 and Opera 7.23. I tried http://www.saneplanet.com/clients/bowman/style2.htm in IE 6 again and the menus definietly only open up in the wrong location (on the left side of the screen).

0
 
LVL 36

Expert Comment

by:Zyloch
ID: 10963851
Yes, I see what you are talking about. It seems that sometimes it is like that, and sometimes it's not... I'll check it out

--Zyloch
0
 
LVL 36

Expert Comment

by:Zyloch
ID: 10963898
I tested a bit in IE6 and I found this is what happens: For some reason, both sites do not use the cookies correctly. To formally test style2.htm, you would need one other page like about_me2.htm that has all the stylesheets like

<link ref="alternate" and only one <link ref="stylesheet"

The menu is a slight problem. There is no real problem in IE6. In style2.htm, there is a problem with the menu most of the time. However, in style1.htm, if you reload the page while your mouse cursor is on a menu, the problem occurs. You only need to move the cursor away from the menu and then over the menu again and it should work fine. Is there a reason both cookies are not working? because in my testing, they worked perfect.

--Zyloch
0
 

Author Comment

by:polaatx
ID: 10965107
No, I have no idea what is wrong.

I took a chance and changed the whole site to the scheme we had in style1 (changing the body tag to just <body>). It worked well for a while in IE and then for a a moment the menu items started misbehaving and then eversince I haven't been able to get it to misbehave in IE 5.01, 5.5 and 6.0. I am going to try it from other computers.

Works fine in Opera. Doesn't work in Netscape 7.1, which doesn't bother me.

I don't have a Mac. Can you look at in the Mac?
0

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

CSS3 Custom checkboxes This article shows how to style the checkbox form element using only CSS. Works in: Chrome, FF, Safari, Opera, IE9+ Uses modernizr.js to check for :checked pseudo class, falling back to plain old checkboxes (IE8 and bel…
As a result of several questions about how to use Bootstrap I thought it would be a good idea to write down the development aspect of creating a Bootstrapped website in as little time as possible. Part 1 of this article will only concentrate on g…
In this tutorial viewers will learn how add a scalable full-width header using CSS3. Create a new HTML document with an internal stylesheet. Set a tiled background.:  Create a new div and name it Header. Position it with position:absolute at the top…
In this tutorial viewers will learn how to embed custom externally-hosted Google Fonts using the Google Font API in CSS Go to the Google Fonts website at google.com/fonts: Browse or search based on font properties or name to find a suitable font for…

726 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question