Question

First off, I'm working on an app that's written such that some of your typical debugging tools can't be used (or at least I can't figure out how :).

JavaScript, html, etc are all "cooked" and encoded (I think; I'm a little fuzzy on how the process works) before being deployed, so I can't attach VS 2005 to ie, and firebug lite doesn't work well. Also, the interface is in frames (yuck), so some other tools don't work as well.

Firebug works great in Firefox, which isn't having this problem (nor is Safari), so I'm hoping someone might spot something "obviously" wrong with the way my code will play with IE. There's more information that can be given about its quirkiness, but let's start with this.

Basically, I have a function that "collapses" tables into their headers by making normal table rows not visible. I have "onclick='toggleDisplay("theTableElement", "theCollapseImageElement")'" in the <tr> tags, and tables start off with "class='closed'".

Single clicks collapse and expand tables in FF & Safari, but IE tables require multiple clicks (a seemingly arbitrary number between 1 and 5) to expand. Sometimes after initially getting "opened", the tables will expand and collapse with a single click for a little while, only to eventually revert to requiring multiple clicks. I can tell from what little I can see in Visual Studio that the function is actually being reached each time. Thanks in advance for any advice!

Here's the JS code:

bURL_RM_RID="some image prefix";
CLOSED_TBL="closed";
OPEN_TBL="open";
CLOSED_IMG= bURL_RM_RID+'166';
OPENED_IMG= bURL_RM_RID+'167';

//collapses/expands tbl (a table) and swaps out the image tblimg
function toggleDisplay(tbl, tblimg) {
    var rowVisible;
    var tblclass = tbl.getAttribute("class");
    var tblRows = tbl.rows;
    var img = tblimg;

    //Are we expanding or collapsing the table?
    if (tblclass == CLOSED_TBL) rowVisible = false;
    else rowVisible = true;

    for (i = 0; i < tblRows.length; i++) {
        if (tblRows[i].className != "headerRow") {
            tblRows[i].style.display = (rowVisible) ? "none" : "";
        }
    }

    //set the collapse images to the correct state and swap the class name
    rowVisible = !rowVisible;
    if (rowVisible) {
        img.setAttribute("src", CLOSED_IMG);
        tbl.setAttribute("class",OPEN_TBL);     
    }
    else {
        img.setAttribute("src", OPENED_IMG);
        tbl.setAttribute("class",CLOSED_TBL);
    }
}

­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­

Was it helpful?

Solution

setAttribute is unreliable in IE. It treats attribute access and object property access as the same thing, so because the DOM property for the 'class' attribute is called 'className', you would have to use that instead on IE.

This bug is fixed in the new IE8 beta, but it is easier simply to use the DOM Level 1 HTML property directly:

img.src= CLOSED_IMAGE;
tbl.className= OPEN_TBL;

You can also do the table folding in the stylesheet, which will be faster and will save you the bother of having to loop over the table rows in script:

table.closed tr { display: none; }

OTHER TIPS

Have you tried changing this line

tblRows[i].style.display = (rowVisible) ? "none" : "";

to something like

tblRows[i].style.display = (rowVisible) ? "none" : "table-row";

or

tblRows[i].style.display = (rowVisible) ? "none" : "auto";

You might want to place your onclick call on the actual <tr> tag rather than the individual <th> tags. This way you have less JS in your HTML which will make it more maintainable.

If you enable script debugging in IE (Tools->Internet Options->Advanced) and put a 'debugger;' statement in the code, IE will automatically bring up Visual Studio when it hits the debugger statement.

I have had issues with this in IE. If I remember correctly, I needed to put an initial value for the "display" style, directly on the HTML as it was initially generated. For example:

<table>
  <tr style="display:none"> ... </tr>
  <tr style="display:"> ... </tr>
</table>

Then I could use JavaScript to change the style, the way you're doing it.

I always use style.display = "block" and style.display = "none"

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top