3

I worked out any single instance of document.getElementById("MyID").innerHTML = "A value" in this Javascript World Clock guide causes Wordpress Admin not to load completely and breaks various areas of the Wordpress admin interface.

I solved it by replacing each instance with jQuery("#MyID").html("A value")) which appears to work fine. What is causing .innerHTML to fail miserably but not JQuery().html()?

1
  • 1
    I don't think it does, if I recall correctly they both reset the DOM. Commented Apr 12, 2011 at 13:08

4 Answers 4

3

At a guess I would suspect either browser-specific stuff or document.getElementById("MyID") returns null, causing an exception.

Sign up to request clarification or add additional context in comments.

5 Comments

If document.getElementByID("MyID") returns null, then jQuery("#MyID") should return an empty jQuery object, so the .html() call wouldn't do anything.
@justkt not doing anything is different from throwing an exception if there was stuff after the call.
right, but the question seems to indicate that the DOM is changed by .html().
@justkt "solved it by replacing each instance" implies that one or more of them may have been broken, although it isn't clear.
No I didn't see any errors in the original .innerHTML code. I actually have just three clocks with identical syntax apart from the values I passed to the functions. It was only when I commented out all references to innerHTML that the errors were resolved.
0

This is likely the pertinent part of the jQuery source:

try {
    for ( var i = 0, l = this.length; i < l; i++ ) {
        // Remove element nodes and prevent memory leaks
        if ( this[i].nodeType === 1 ) {
            jQuery.cleanData( this[i].getElementsByTagName("*") );
            this[i].innerHTML = value;
        }
    }

    // If using innerHTML throws an exception, use the fallback method
} catch(e) {
    this.empty().append( value );
}

Note that it handles exceptions thrown.

See it for yourself in 1.5.2.

1 Comment

I'm marking this is as my accepted answer. That doesn't mean I know exactly why it works but its clear JQuery is doing a more thorough job with error checking.
0

This is how jQuery does it:

html: function( value ) {
    if ( value === undefined ) {
        return this[0] && this[0].nodeType === 1 ?
            this[0].innerHTML.replace(rinlinejQuery, "") :
            null;

    // See if we can take a shortcut and just use innerHTML
    } else if ( typeof value === "string" && !rnocache.test( value ) &&
        (jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) &&
        !wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) {

        value = value.replace(rxhtmlTag, "<$1></$2>");

        try {
            for ( var i = 0, l = this.length; i < l; i++ ) {
                // Remove element nodes and prevent memory leaks
                if ( this[i].nodeType === 1 ) {
                    jQuery.cleanData( this[i].getElementsByTagName("*") );
                    this[i].innerHTML = value;
                }
            }

        // If using innerHTML throws an exception, use the fallback method
        } catch(e) {
            this.empty().append( value );
        }

    } else if ( jQuery.isFunction( value ) ) {
        this.each(function(i){
            var self = jQuery( this );

            self.html( value.call(this, i, self.html()) );
        });

    } else {
        this.empty().append( value );
    }

    return this;
},

5 Comments

And how does dumping the source code for the html() method answer the question?
Sorry but I agree with @BoltClock, this is just pointing me to what I'm already using. You would have to explain why this works to answer my question.
@edwinbradford: I don't understand how this can not be helpful. You are wondering why html() works and not innerHTML="". What I posted above is exactly how jQuery does its html method. If you can not deduct to why this works the way it does, you should not have marked the other post that shows (only part of) what the method does either.
I think it is because the other answer makes note of how jQuery is catching exceptions and if so, using a fall-back. It is also only showing the part of the code relevant to the explanation.
Thank you John, John's reply summarizes my reasoning very well. Thanks also to you @Shaz for submitting an answer.
0

About the only difference between what you tried and what jQuery's html method might be doing is removing the content of the element before inserting the new content. So try removing the content first and if you are only inserting plain text, create and insert a text node instead of setting the innerHTML.

So:

function replaceContent(id, s) {
  var el = document.getElementById(id);
  if (el) {
    while (el.firstChild) {
      el.removeChild(el.firstChild);
    }
    el.appendChild(document.createTextNode(s));
  }
}

1 Comment

Yes I wondered about this. The element being referenced was empty, I tried changing it from a <div> to a <span> and also tried a <p> in case it preferred text elements but it made no difference.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.