admin 管理员组

文章数量: 1086019

Run the following piece of jQuery:

$('body').append('<p><span><ul><li>test</li></ul></span></p>');

I would expect this:

<p>
  <span>
    <ul>
      <li>test</li>
    </ul>
  </span>
</p>

However, the result is this:

<p>
  <span></span>
</p>
<ul>
  <li>test</li>
</ul>

Why does the ul tag break out of span and p? This is valid HTML markup.

* UPDATE *

The p tag seems to be the problem. If you run the following:

$('body').append('<span><ul><li>test</li></ul></span>');

then

<span>
  <ul>
    <li>test</li>
  </ul>
</span>

will generate properly.

Run the following piece of jQuery:

$('body').append('<p><span><ul><li>test</li></ul></span></p>');

I would expect this:

<p>
  <span>
    <ul>
      <li>test</li>
    </ul>
  </span>
</p>

However, the result is this:

<p>
  <span></span>
</p>
<ul>
  <li>test</li>
</ul>

Why does the ul tag break out of span and p? This is valid HTML markup.

* UPDATE *

The p tag seems to be the problem. If you run the following:

$('body').append('<span><ul><li>test</li></ul></span>');

then

<span>
  <ul>
    <li>test</li>
  </ul>
</span>

will generate properly.

Share Improve this question edited Jan 8, 2016 at 18:19 Jon Cursi asked Jan 8, 2016 at 17:51 Jon CursiJon Cursi 3,3814 gold badges28 silver badges53 bronze badges 6
  • Try appending actual element objects, and not a string – Sterling Archer Commented Jan 8, 2016 at 17:53
  • 7 No, that's actually not valid HTML. See: validator.w3 – Josh Crozier Commented Jan 8, 2016 at 17:54
  • @SterlingArcher: jQuery's append is just fine with HTML strings. – T.J. Crowder Commented Jan 8, 2016 at 17:55
  • @T.J.Crowder I should have clarified -- I know it works, it's just cleaner (IMO) to build the objects – Sterling Archer Commented Jan 8, 2016 at 17:56
  • FYI, I've updated my answer to address your update. – T.J. Crowder Commented Jan 8, 2016 at 18:13
 |  Show 1 more ment

3 Answers 3

Reset to default 9

How to append a <ul> tag inside a <p> or <span>?

You can't, it's invalid. So what you're seeing is the browser trying to rearrange it to make it valid.

The content model of span elements (e.g., what they're allowed to have in them) is "phrasing content" (things like em and such). (Same for p elements.) ul elements are only valid where "flow content" (like paragraphs and divs) is expected.

To fix it, don't try to put a ul inside a span or a p. You could remove the span and the p and use a div, for instance:

$('body').append('<div><ul><li>test</li></ul></div>');

...or just use the ul directly without a wrapper around it.


Re your update:

If you add the following markup to an html document

...

And then open the page in your favorite browser, it will open correctly. Try it!

Sure — because the browser rearranges it. For instance, this snippet:

<p>
  <span>
    <ul>
      <li>test</li>
    </ul>
  </span>
</p>

Is turned into this DOM by Chrome:

Note how the ul is not inside the p or span — it's exactly the result you said you were getting.

That said, browsers do a lot to try to tolerate invalid markup and structures. But using valid markup and structures is generally the way to go.

You're putting a block-level element inside an inline element. Also, you wouldn't normally put a list in a paragraph.

$('body').append('<div><ul><li>test</li></ul></div>');

As already explained, your markup is invalid HTML and won't be parsed as you expected.

However, you can still do it using DOM manipulations.

document.body
.appendChild(document.createElement('p'))
.appendChild(document.createElement('span'))
.appendChild(document.createElement('ul'))
.appendChild(document.createElement('li'))
.appendChild(document.createTextNode('test'))

Not remended because it's semantically wrong, but it's possible.

本文标签: javascriptHow to append a ul tag inside a P or span tagStack Overflow