Solved

StyleSwitcher doesn't work in IE 6

Posted on 2004-04-29
12
536 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
  • 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
 

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
Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

 

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

Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

Join & Write a Comment

SASS allows you to treat your CSS code in a more OOP way. Let's have a look on how you can structure your code in order for it to be easily maintained and reused.
CSS is a visual language used to classify objects and define rules about how they should be displayed. CSS skills aren’t restricted to developers anymore, there is a big benefit to having a basic understanding of the language, regardless of your occ…
In this Micro Tutorial viewers will learn how to create a CSS image sprite (In a later tutorial, viewers will learn how to use CSS and HTML to create a navigation menu using this sprite) Open a new Photoshop document with a width of (Icon width)x(N…
In this tutorial viewers will learn how to style a decorative dropcap for the first letter in a paragraph using CSS. In CSS, create a new paragraph class by typing "p.fancy": Then, to style only the first letter of the first sentence, include the ps…

708 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

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now