0

Here's the basic setup: We're adding some HTML inside textareas using JavaScript/jQuery. Test 1 does not have a <style> tag, while Test 2 does.

<textarea"><div><style></style><span>Baseline</span></div></textarea>
<textarea id="test1"></textarea>
<textarea id="test2"></textarea>

<script>
    var test1HTML = '<div><span>Test1</span></div>';
    var test2HTML = '<div><style></style><span>Test2</span></div>';

    document.getElementById("test1").innerHTML = test1HTML;
    document.getElementById("test2").innerHTML = test2HTML;
</script>

The above works as expected: all text areas show the HTML code.

But if we use jQuery's .html function to add the content, then Test 2 does not display correctly. It appears to add the content as actual elements, rather than text.

$(document).ready(function(){
    $('#test1').html(test1HTML);
    $('#test2').html(test2HTML); // Causes some kind of problem
});

If we replace .html with .text, then both tests again work as expected.

What's going on with Test 2 using .html? Why does adding a <style> tag change the way .html adds the content? Why do all other methods work correctly?

(FWIW - browser is Chrome 39.0.2171.95 m)

Luke
  • 18,811
  • 16
  • 99
  • 115
  • 3
    Setting the contents of a ` – Pointy Jan 05 '15 at 18:51
  • 4
    Textareas are form controls. You should be using `.val()` to set its "content" (value). – Cᴏʀʏ Jan 05 '15 at 18:52
  • Please check this answer: http://stackoverflow.com/a/16844668 Using – Mike W Jan 05 '15 at 18:54
  • 1
    Also good to know: The "inner HTML" of a ` – Felix Kling Jan 05 '15 at 18:55

2 Answers2

1

jQuery checks the value you're supplying to .html() for <script>, <style> and <link> tags (among several other things). Only if it does not contain them will it continue to set the .innerHTML property of the matched elements.

However, if the value does contain any of those tags, then jQuery chooses to execute $(element).empty().append(content); instead, which appends the text value (node) as a child element.

That should at least explain the difference in behavior.

Here's an excerpt from the source code (v1.11.1):

html: function( value ) {
    return access( this, function( value ) {
        var elem = this[ 0 ] || {};
        // ...ommitted
        // See if we can take a shortcut and just use innerHTML
        if ( typeof value === "string" && !rnoInnerhtml.test( value )) //...
            // ...
            elem.innerHTML = value;
            // ...
        }
        // ... else ... 
        this.empty().append( value );
        // .... end if
    }, null, value, arguments.length );
},

The rnoInnerhtml regular expression is: /<(?:script|style|link)/i,

Cᴏʀʏ
  • 105,112
  • 20
  • 162
  • 194
0

You should use the .val method:

$('#test1').val(test2HTML);
Adilson de Almeida Jr
  • 2,761
  • 21
  • 37
  • OP not asking for method to accomplish this, but asking about the differences b/w the methods attempted and associated results. – Todd Jan 05 '15 at 18:55