MSIE : jQuery's append()/html() not working, resorted to getElementById().innerHTML

13,619

I guess you had to be there. Here are some possible points of failue:

  • jQuery.clean: The function that makes the fragment that gets added to the DOM.

    This could be possible if the doctype is bad, or if the response HTML is flawed in some way that makes the clean function fail, thus leaving nothing to be inserted into the DOM.

  • jQuery.fn.append: Adding the rendered response fragment to the DOM.

    Let's say that, because jQuery adds content to the DOM with appendChild rather than innerHTML, a bug causes IE to be unaware that the DOM has changed and not render the signaled changes. This would then get bypassed when you use innerHTML.

    It's not clear from your question if you have verified that the injected HTML is indeed there. This would be testable with something like this:

    $$.empty().append(data);
    alert( $$.parent()[0].innerHTML );
    $$.show();
    
  • jQuery.fn.show(): Displaying the results.

    It's not clear from your question if the ultimate failure is because the content isn't being put into the DOM, or if it just isn't being displayed? If the container has a padding and a background, do you see it?

    The show function is more complex than just adding .style.display='block' on the element. It won't display the element if it thinks it is hidden, which IE may sometimes have strange ideas on. Does replacing show() with manually setting display change anything?

It is clear that there is a difference in how IE treats the stage/dev page and the live site. My first steps would be to try to discover the difference between them. HTTP Headings, encoding, doctypes, extra scripts, extra css, even whitespace... Some seemingly minor difference is the cause of this bug.

Inn any case, you should prepare a reduced test case of only the bare necessities required to replicate this bug. Even if you don't find a cure for it that you are comfortable with, the test case should be send along with your bug report to jQuery.

Share:
13,619
Chauncey McAskill
Author by

Chauncey McAskill

Oh the things I do for England.

Updated on June 19, 2022

Comments

  • Chauncey McAskill
    Chauncey McAskill over 1 year

    This is a long one,

    The Premise

    Was called in to help out a client with some bug fixing on a current project of theirs. What needed fixing was a jobs listing page. You have a list of jobs, you click one and if JavaScript is activated an AJAX call is made to dynamically load the job's details into an existing element (DIV#emploi_details). If JS isn't activated, it simply reloads the page with the job's details (less important).

    I jumped onto their lab servers to work on the dev website.

    The Problem

    Basically, IE7 (at first) wasn't displaying the content loaded via $().load(). IE6 worked without a hitch with innerHTML. Requests are sent and I get a reply every time. I receive the data, I can alert() it and see it but the actual dumping of the content doesn't work. Safari, Firefox, no problems. The DIV#emploi_details element I'm loading info into has a CSS display:none; in its styleheets and is shown after content is loaded in (other not so important detail).

    show_emploi = function(id, succ_id)
    {
        $('#emploi_details').fadeOut(800, function() {
            var $$ = $(this);
    
            $$.load('emploi_<?php echo $data['lang']; ?>.php', { job_details: 1, ajax: 1, id: id, succ: succ_id, random: (new Date().getTime()) }, function(data, status){
                if (isIE6) document.getElementById('emploi_details').innerHTML = data;
                $$.show();
            });
            $('#bgContent').fadeOut();
        });
    }
    

    The Solution

    At first I was under the impression maybe the $().load() was just acting up, so I changed it for a $.get() for more control over the manipulation of the loaded content.

    $.get('emploi_<?php echo $data['lang']; ?>.php', { job_details: 1, ajax: 1, id: id, succ: succ_id, random: (new Date().getTime()) }, function(data, status){
        $$.empty().append(data).show();
    });
    

    This works. In all browsers including IE6 and IE7. No problem. Weird, but you know if it works and its fullproof, don't ask questions.

    The Plot Twist

    Now here's where shit gets weird. I considered the bug fixed and applied the solution to the live website and... it doesn't work. IE just isn't liking it. Baffled after trying $.ajax and all other sorts of stuff I end up using this for the live website :

    $.get('emploi_<?php echo $data['lang']; ?>.php', { job_details: 1, ajax: 1, id: id, succ: succ_id, random: (new Date().getTime()) }, function(data, status){
        document.getElementById('emploi_details').innerHTML = data;
        $$.show();
    });
    

    And it works on all browsers, because there's nothing like barebones JS to get stuff done. Necessarily, this fix also works on the dev website.

    The 'To Be Continued'

    There is something in the function of embedding of the content that isn't clicking for all browsers (and clearly servers).

    All in all, my question is a WTF question. I can't understand why one works on one side and the same doesn't work on the other side or even why it never worked properly in the beginning ($().load()). It's clearly not different jQuery versions (1.2.6) since it was my first instinct to verify the framework version.

    Anyway, interesting mystery IMO.

    Hope someone out there in Stackland has the god-given answer.

    Thanks

  • Chauncey McAskill
    Chauncey McAskill over 14 years
    Thanks for the detailed response. Indeed, I forgot to mention that I did perform tests (your suggested alert call) after appending content to the DOM and IE would display that the element was empty. I also did try without the jQuery.fn.show() (which simply added a dashed border to the left) and kept the element displayed by default and still no content would be appended. I'll see if my client will allow me to perform some tests to see if there are any other possible anomalies. I'm most definitely curious about what is differentiating the dev from the live.