3

I have previously answered this question, but I do not fully understand why the answer is correct. The gist of the answer:

<p id="jqrender"></p>

$(function() {
    $('#jqrender').html("<a href=http://www.website.com/>foo bar</a>");
});

On latest Chrome on OSX, jQuery interprets this as <a href="website.com"></a>foo bar. Which makes sense, I guess, because it thinks the closest markup correction is <a href="website" />. But natively, Chrome itself will interpret the markup as <a href="website.com/">foo bar</a>.

Why is this? I would like a technical answer, what part of jQuery is doing this markup-fixing, what are some general rules it follows, and how can I guess how jQuery will react to other broken markup?

Community
  • 1
  • 1
000
  • 26,951
  • 10
  • 71
  • 101
  • http://james.padolsey.com/jquery/#v=1.10.2&fn=jQuery.buildFragment – Quentin Oct 03 '13 at 22:40
  • I think it essentially translates `.html("string")` to `.html($("string"))`. And HTML's fragment parser tries to be clever in allowing you to supply just opening tags, or things like `
    `, and it constructs DOM elements from it.
    – Barmar Oct 03 '13 at 22:44

1 Answers1

2

The offending line in jQuery source is here: https://github.com/jquery/jquery/blob/master/src/manipulation.js#L222

tmp.innerHTML = wrap[ 1 ] + elem.replace( rxhtmlTag, "<$1></$2>" ) + wrap[ 2 ];

Where rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi
and elem is the fragment of potentially broken markup.

The result of that replace call, for that input, is <a href=http://www.website.com></a>foo bar</a>.

The browser then does the work of fixing that markup, by removing the ultimate </a>.

So the other point in the question can be answered with: This particular case will also affect all tags except area, br, col, embed, hr, img, input, link, meta, and param.

tl;dr: https://stackoverflow.com/a/1732454/1253312

Community
  • 1
  • 1
000
  • 26,951
  • 10
  • 71
  • 101