Search code examples
jqueryjquery-selectorsappendrelational

jquery append doesn't work with relational selectors


the append() method seems to work only with simple selectors like $("#myid") but not with relational selector like $(#myid>ul). Do you have the same problem?

EXAMPLE Try this: http://www.w3schools.com/jquery/tryit.asp?filename=tryjquery_html_append_ref

If I change the code this way:

<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<script>
$(document).ready(function(){
    $("#btn1").click(function(){
        $("p").append(" <b>Appended text</b>.");
    });
    $("#btn2").click(function(){
        $("p>ol").append("<li>Appended item</li>");
    });
});
</script>
</head>
<body>
<p>This is a paragraph.</p>
<p>This is another paragraph.
 <ol>
<li>List item 1</li>
<li>List item 2</li>
<li>List item 3</li>
</ol>
</p>
<button id="btn1">Append text</button>
</body>
</html>

the "Append list item" button doesn't work any more, because $("p>ol").append("<li>Appended item</li>") doesn't work, as it has a relational selector.


Solution

  • jQuery works fine. It's your markup that's screwed up. It's against the HTML spec to include flow elements like ol in a paragraph element. Only phrasing elements are permitted in a p element

    Paragraphs may only contain phrasing content: w3c spec
    Phrasing content does not include the ol element: w3c again

    Notice in the following example how the $('p + ol') selector correctly targets the ol. this is because of a little known rule for the p element in the HTML spec. Paragraphs automatically terminate without the need of an ending paragraph tag if they are followed by ol or other flow content. (See "Tag Omission")

    $('p + ol').css({color: 'red'});
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <p>
      WARNING! this is invalid markup.
      <ol>
        <li>List</li>
        <li>List</li>
        <li>List</li>
      </ol>
    </p>