Sahuagin Sahuagin - 1 month ago 6
HTML Question

Search elements including roots and descendents

What's a good way to search a small set of elements structured like this? I want to be able to find any element given its ID, without having to know exactly where I'm looking for it.

const elements = $(`
<div id="a">
<div id="aa"></div>
<div id="ab"></div>
</div>
<div id="b">
<div id="ba"></div>
<div id="bb"></div>
</div>
`);



  • .find("#id")
    can find
    aa
    , but not
    ba
    or
    b

  • .filter("#id")
    can find
    a
    and
    b
    , but not
    aa
    or
    bb

  • I also tried
    .siblings().addBack().find("#id")
    , but that doesn't seem to work either (can't even find
    a
    )



I can't seem to get around the fact that
find
misses the root elements, but
filter
misses the descendent elements. I need some combination of the two...

Answer

From jQuery 1.11.2 and 2.1.2 onwards you can effectively use a documentFragment like this:

$(document.createDocumentFragment())

This does not introduce an element. If you append the element contents to it, and query the parent of #a you'll get no match.

var elements = $(`
   <div id="a">
      <div id="aa"></div>
      <div id="ab"></div>
   </div>
   <div id="b">
      <div id="ba"></div>
      <div id="bb"></div>
   </div>
`);

// wrap elements in a document fragment
elements = $(document.createDocumentFragment()).append(elements);

// elements.find('#a') works, but second argument of $() can be used: 
console.log('#a', $('#a', elements).length);
console.log('#ab', $('#ab', elements).length);
console.log('#ba', $('#ba', elements).length);

console.log('parents of #a:', $('#a', elements).parent().length);
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.0/jquery.js"></script>