#529 ✓resolved
Riki Fridrich

Element constructor doesn't add className in IE8

Reported by Riki Fridrich | January 26th, 2009 @ 11:03 AM | in 1.6.1

When creating a new Element using constructor, Internet Explorer 8 doesn't add className to the new element.

You can see test case at: http://fczbkk.com/bordel/builder...

The code itself:

var myElement = new Element( 'div', { 'className' : 'firstClassName' } ); alert( myElement.className ); // IE8 returns empty string myElement.addClassName( 'secondClassName' ); alert( myElement.className ); // IE8 returns only 'secondClassName'

I have tested both attribute names: 'class' and 'className'. The same result.

This bug is specific to IE8. All other browsers (including IE7 and lower) work just fine.

Comments and changes to this ticket

  • Riki Fridrich

    Riki Fridrich January 26th, 2009 @ 11:05 AM

    Sorry about the formatting. This should be better:

    
    var myElement = new Element( 'div', { 'className' : 'firstClassName' } );
    alert( myElement.className ); // IE8 returns empty string
    myElement.addClassName( 'secondClassName' );
    alert( myElement.className ); // IE8 returns only 'secondClassName'
    
  • Juriy Zaytsev

    Juriy Zaytsev January 26th, 2009 @ 02:06 PM

    • Milestone set to 1.7
    • State changed from “new” to “bug”
  • Nick Stakenburg

    Nick Stakenburg February 28th, 2009 @ 10:44 PM

    • Tag set to needs_patch, needs_tests

    Maybe this would be better on 1.6.0.4 since effort was put into making sure tests pass on IE8 for that milestone.

  • Andrew Dupont

    Andrew Dupont March 1st, 2009 @ 12:10 AM

    • Assigned user set to “Andrew Dupont”
    • Milestone changed from 1.7 to 1.6.1
  • GitHub Robot

    GitHub Robot March 9th, 2009 @ 02:33 AM

    • State changed from “bug” to “resolved”

    (from [8f697f3e85aff85d121868261588dae6551821b1]) Add tests to ensure IE8 properly assigns a class name in the Element constructor. [#529 state:resolved] (Riki Fridrich, Andrew Dupont) http://github.com/sstephenson/pr...

  • Nick Stakenburg

    Nick Stakenburg March 9th, 2009 @ 01:29 PM

    Adding tests doesn't fix the problem Riki showed.

    element.select('.class').length on elements created with new Element gives a length of 0 in IE8.

  • rvagg

    rvagg March 20th, 2009 @ 04:06 AM

    This ticket needs its state changed back doesn't it? I don't believe it's actually resolved.

  • Tim Wilson

    Tim Wilson March 20th, 2009 @ 05:53 AM

    Found a workaround. Just did some testing in IE8, the problem appears to be linked to @@@'className' : 'firstClassName'@@@

    Instead do the following...

    
    var myElement = new Element( 'div' );
    myElement .addClassName('firstClassName');
    
  • rvagg

    rvagg March 20th, 2009 @ 06:11 AM

    
    var myElement = new Element( 'div' ).addClassName('firstClassName');
    

    since addClassName chained anyway.

  • butz

    butz April 21st, 2009 @ 11:21 AM

    • Tag changed from needs_patch, needs_tests to bug

    Sorry, state must be changed, right?

  • butz

    butz April 21st, 2009 @ 02:39 PM

    • Tag changed from bug to bug, workaround

    msie 8.0 prototype.js : 1.6.0.3 !unofficial quikfix!

    idea: within prototype.js, within the method 'Element.writeAttribute()' (near #1800) the 'default' JS call:

    
    element.setAttribute(name, value);
    

    doesn't work properly for constructor's call like:

    
    myDiv = new Element('div', {'class' : 'myCssClass'});
    

    reason (?): because the mapping for msie 8.0 for the variable 'name' with the value 'className' doesn't return 'class', which is needed for

    
    element.setAttribute('class', 'myCssClass');
    

    extension / workaround:

    1. extending prototype.js variable 'Prototype' (near #39, after 'var Prototype = {...}'):
    
    if (Prototype.Browser.IE) {
    	if (/MSIE (\d+\.\d+);/.test(navigator.userAgent)) {
    		Prototype.BrowserFeatures['Version'] = new Number(RegExp.$1);
    	}
    }
    
    1. adding workaround within Element.writeAttribute() (near #1800):
    
    if (value === false || value === null) {
      element.removeAttribute(name);
    }
    else if (value === true) {
      element.setAttribute(name, name);
    }
    else {
      // element.setAttribute(name, value);
      if (name === 'className' && Prototype.Browser.IE && Prototype.BrowserFeatures.Version == 8) element.setAttribute('class', value);
      else element.setAttribute(name, value);
    }
    

    other suggestion??

  • Juriy Zaytsev

    Juriy Zaytsev April 22nd, 2009 @ 06:57 AM

    other suggestion??

    Do not ever rely on browser sniffing for such basic functionality. Is there a reason you can't use 1.6.1RC1 (which shouldn't have such issues)?

  • butz

    butz April 22nd, 2009 @ 05:28 PM

    @ Juri Zaytsev The reason why we don't want to use a RC is, beacause it's a RC ;-). We are using Prototype within a huge project and we prefer to use code which is as stabel as possible.

  • Juriy Zaytsev

    Juriy Zaytsev April 22nd, 2009 @ 05:38 PM

    So you think that applying an unofficial sniff-based "quickfix" to 1.6.0.3 will lead to a more stable code?

  • butz

    butz April 22nd, 2009 @ 05:59 PM

    @ Juri Zaytsev: Sorry, I woudn't criticize your code at all!

    Just found a problem, tried to find a solution, well knowing that my quickfix isn't the final solution at all :-)!

    It was the first time where I used prototype.js, found the problem, had a look within the prototype.js, tried to find a solution and help you guys to optimize your code - that's it.

  • paddy keane

    paddy keane April 23rd, 2009 @ 08:05 PM

    as far as I know this issue is still unresolved? any change someone can change the bug status to make everyone aware this is still a problem? thxs ;)

  • Chris Hawkins

    Chris Hawkins July 7th, 2009 @ 10:54 PM

    Here is a solution that addresses all three cases of name value pairs and does not rely on sniffing to get the version number. It should be inserted at line 1818 (at the end of the for loop in writeAttribute). Basically, it just checks to see if the set or remove attribute was successful and tries again with 'class' if it was not.

    var ieClass = (name == 'className');
    if(ieClass && value && element.className == '')
    {
        element.removeAttribute('className');
        if(value === true) {
            element.setAttribute('class', 'class'); }
        else {
            element.setAttribute('class', value); }
    }
    else if(ieClass && (value === false || value === null) && element.className != '') {
        element.removeAttribute('class'); }
    

Please Sign in or create a free account to add a new ticket.

With your very own profile, you can contribute to projects, track your activity, watch tickets, receive and update tickets through your email and much more.

New-ticket Create new ticket

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile »

The Prototype JavaScript library.

Shared Ticket Bins

Referenced by

Pages