views:

605

answers:

2

I'm wrestling with a ridiculous problem in IE6. I render a page full of data on the server-side, and then iterate through the results (rows of an HTML table) on the client side, updating each row in sequence with the results of an AJAX call on each row. (I don't want to use .each(), don't ask...)

IE6 will not show anything on the client side until all of the code in the document.ready() block completes. In the code below you'll see it's reproducible without the AJAX db calls: take a table of 100 rows, and when the document is ready, iterate through the TR collection and replace the text node in each TD. IE6 won't show a thing until the jQuery code is finished executing.

Here's the test case:

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<head>
<script src="scripts/jquery-1.3.2.min.js" type="text/javascript"></script>
<script type="text/javascript">
    $(document).ready( function() {  
        var totalRows = $('table tr').size();
        for (var i=0; i<totalRows; i++) {
            var currentRow=$('table tr').eq(i);
            var cellTarget = currentRow.children(0);
            cellTarget.html('and after');
            }

});
</script>
</head>
<body>
<table>
<tr><td>before</td></tr>
<tr><td>before</td></tr>
<tr><td>before</td></tr>
... repeat 97 more times ...
</table>
</body>
</html>

Here's the nutty part: put an alert ('hello'); after updating the TD text node and as the modal alert box pops up you can watch the rendered table underneath updating as it iterates through the row. I've tried using various sleep functions after the text node update to no avail -- it doesn't seem to have an effect other than slowing down the overall execution time. I've tried moving the script blocks to the end of the file and that doesn't seem to fix the issue either.

Any ideas?

A: 

Have you tried keeping the function at the top, but keep it out of the $(document).ready(), and set it as its own function. And then at the bottom of the document, put a script tag that calls that function?

Also, another possibility is to put defer="true" in the script tag.

Thomas
Neither tactic worked. Good thoughts though, I forgot about defer.
Thumbkin
A: 

I don't have a copy of IE6 to test on right now, but what if you used jQuery's .each functionality?

The JS snippet would boil down to this:

$(document).ready( function() {
    $('table tr').each(function(i){
     // In this function, 'this' is bound to your table row
     // The argument i receives the same value as your original loop, 
     // although it's not necessary in this style.
     // Also, 'this' is actually bound to the DOM element, 
     // NOT a jQuery object, so if you want to use jQuery stuff,
     // you gotta $(wrap) it.
     $(this).html('and after');
     // Alternately, you could just this.innerHTML = 'and after';
    });
});

I've also put it up on JS Bin, you can view it live at http://jsbin.com/aguxa or edit it at http://jsbin.com/aguxa/edit - any edits you make and save won't alter the original, so tweak away (such as adding in that alert, which I don't relish trying with 100 table rows ;))

Brian Arnold
Same behavior as my example in IE6 -- results aren't rendered until the entire script block has finished executing. Have observed the same behavior in IE 8 in standard mode and compatibility mode.
Thumbkin
Hmm - based on http://support.microsoft.com/?kbid=2000262 - which isn't directly related, but talks about how IE has problems with manipulating large DOM collections - I can't help but wonder if perhaps it's just IE and that's that. :/That being said, I did also have one time where some elements weren't re-rendering properly after changes. It's horribly hacky, but I found that using jQuery on the parent node caused a refresh.http://jsbin.com/isote has the code. I know it's an awful hack, but it worked for me once to cause a refresh. Stupid IE.
Brian Arnold
Works partially in IE8, not at all in IE6.
Thumbkin
Had a similiar issue (changed hieght wouldn't update), but not using jQuery and just using javascript seemed to fix it.targetElementNode.style['height'] = someNumber as opposed to $('#targetElementNodeID').css('height',someNumber)
Bless Yahu