Tuesday, April 04, 2006

Dynamically Changing Classes

Internet Explorer doesn't notice a fucking thing.

Say I have the following:
<div class="thin">stuff</div>
and I want to using unintrusive JavaScript to change it to this:
<div class="wide">stuff</div>
I would hope that would work fine, like it does for every other browser, but Internet Explorer simply ignores it.

Well, I suppose it does notice the class change - if I call (the element in question).getAttribute('class') it returns the correct value. I just completely fucking ignores all styles associated with that class.

I've tried a number of "cheats" to try tricking Internet Explorer into doing the useful thing:
  1. (the element in question).innerHTML = '' + (the element in question).innerHTML
  2. re-setting the stylesheet in question
  3. even looping through the stylesheets, disabling them and then enabling them after a short timeout to make sure they turn off in the first place
No change.

So thanks to Internet Explorer, I now get to get several blocks of "IE blows fucking chunks and I have to write this load of JavaScript when a single class swap should do the trick" instead of moving on to something else to get this project done.

Labels: ,

17 Comments:

Anonymous C said...

Yeh Internet Explorer is always the bane of my life too, I really hate it!

Do you have an example of changing classNames? I'm sure this works ok so I am guessing I am missing exactly where you are comin from, a small example would be quality.

2:40 AM  
Blogger The Hater said...

"Do you have an example of changing classNames? I'm sure this works ok so I am guessing I am missing exactly where you are comin from, a small example would be quality."

Sure thing:

1. Go to http://www.yahoo.com/ in Firefox
2. Paste the following into the location bar (everything from "javascript:" to the semi-colon) and hit return: javascript:void(document.getElementById('footer1').setAttribute('class', 'hidden'));
3. You should see the bottom part of the featured content directly in the middle of the page disappear.
4. Change 'hidden' to 'current' and hit return again
5. You should now see it reappear.

Now do the same in IE. I just gave it a shot in IE7 and it didn't do a damn thing. Test to make sure it switched the class and ignored it: once you've switched the class to 'hidden' in IE, paste the following into the location bar and hit return to get it to tell you the current class: javascript:void(alert(document.getElementById('footer1').getAttribute('class')));

9:30 AM  
Blogger The Hater said...

Mother-fucker...

That last line, broken up so you can see the whole goddamn thing:

javascript:void(
alert(
document.getElementById('footer1')
.getAttribute('class')
)
);

There. Just make that one single line without any spaces when you use it.

9:34 AM  
Anonymous 0x15+0x15 said...

Workaround for this: use setAttribute("className", "blah") instead of setAttribute("class", "blah").

From http://www.javascriptkit.com/domref/elementmethods.shtml, documentation of setAttribute:

Sets an attribute's value for the current element. If the attribute doesn't exit yet, it creates the attribute first. Otherwise, the existing attribute is modified with the new value. In IE, the following two pitfalls exist:
To set the "class" attribute, use "className" instead.
The "attributename" parameter is case sensitive by default in IE . This means if you attempt to set the "align" attribute and "Align" already exists on the element, both will be present as a result. To turn off case sensitivity, set the IE-only 2nd parameter of setAttribute() to 0 (instead of default, which is 1).

Yes, IE sucks.

8:08 AM  
Anonymous Anonymous said...

IE sucks!

using:
document.getElementById('li['+liId+']').setAttribute(document.all ? 'className' : 'class', className);

it's not working :(

in Firefox all fine

10:01 AM  
Blogger stephen said...

I found a combination of setAttribute("class","blah") and setAttribute("className","blah") works, also document.getElementById('myDiv').className='blah';
although I've had problems with getElementById in ie7 b4 too!

6:56 AM  
Blogger Sudhansu said...

document.getElementById('li['+liId+']').setAttribute(document.all ? 'className' : 'class', className);

instead of this use i.e use " inplace of '

document.getElementById('li['+liId+']').setAttribute(document.all ? "className" : "class", "Name of Class");

1:07 AM  
Blogger Sudhansu said...

document.getElementById('li['+liId+']').setAttribute(document.all ? 'className' : 'class', className);

use the follwing i.e inplace of ' use "

document.getElementById('li['+liId+']').setAttribute(document.all ? "className" : "class", "NameofClass');

1:08 AM  
Blogger mishoo said...

Guys, use:

element.className = "newClass";

This works, always, in any browser I can think of (probably in Netscape 4 too).

You don't need setAttribute for that. Yes, I know it's standard, but I've actually grown to hate standards (since every browser has their own idea about how to implement them, though I admit IE is the worst).

BTW, element.className is a standard too ( http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-95362176 ), it just happens to be older; I think it's there since DOM level 0, that is, when IE4 was beating the crap out of Netscape 4.

Anywayz. IE truly sucks. Got here by chance (I forgot what was I searching for) and I remember a lot of horrible frustration of my own, as I read your blog. I have an anti-IE site too, though I haven't update it for a long while (www.dropie.com).

And, who the fuck are you anyway? :)

2:47 PM  
Blogger The Hater said...

Mishoo:

Granted, that will mostly work, but I try to stay consistent with my DOM access. If only IE would fucking do the same.

9:51 AM  
Blogger Matthew Dybwad said...

Can anyone lend a hand with this bit of code, I'm trying to get IE to change the class of the first object it finds with the name checkItem to checkOn . None of the workarounds I've seen seem to work for me.


highlightItem();
function highlightItem(){
var itemHighlighter = document.getElementsByName('checkItem');
itemHighlighter[0].className="checkOn";
}

5:04 PM  
Anonymous toddB said...

Hater,

I have had so much frustation with this issue as well. It doesn't only apply to when you dynamically change the class, but also applies when you dynamically create elements with a valid CSS class.

My question is, have you found a workaround for this? We all realize this happens, but do you know of a way to fix this, even if it involves alot of Javascript? Would you have to set each style rule individually using js -- ie:

element.style.display='block';
element.style.otherRule='value';

3:22 PM  
Anonymous Anonymous said...

document.getElementById("id").className = "newClassName"; will work in IE6. Just make sure you don't prepend your class names with any character other than a letter, like I did. It took me quite some time to come across an article that showed me the way:

http://patchlog.com/general/css-class-names-in-ie-6/

2:19 PM  
Anonymous Anonymous said...

This works for me on IE7 & FF
IE7:
yourElement.className = "whateverYourClassNameMayBe";
FF:
yourElement.setAttribute("class", "whateverYourClassNameMayBe");

5:14 AM  
Anonymous Anonymous said...

IE SUUUUUUUUCKS!

I've run across this before.. But forgot (way too many IE inconsistencies to keep in my head) so I ended up here and thought 'Doh!'.. :)

IE8 works a lot better... They're 'claiming' standards compliancy... But the release doesn't support the very nice new 'canvas' tag :(.. (There's always Google's ExplorerCanvas)..

I wish MS would just get out the browser business all-together, or just use Gecko or WebKit (like Google Chrome does).

IE Sucks.. sucks sucks sucks..

11:04 PM  
Anonymous Anonymous said...

IE Developers need to get re-educated, maybe learn a thing or two about common sense.

4:33 PM  
Anonymous Kane said...

Well thank you to everyone's comments.

I came across the same problem and here was my work around that I've tested in IE6 and FF

if(obj.getAttribute('className') != null) { // IE bullshit
obj.setAttribute('className','myNewClassName')
} else { // real browsers
obj.setAttribute('class','myNewClassName')
}

Kane

12:34 AM  

Post a Comment

Links to this post:

Create a Link

<< Home