Skip to content
An opposite of `closest()`: find the nearest child that matches a selector, ignore deeper matching children
JavaScript
Branch: master
Clone or download
lolmaus A warning that `.find().filter()` may be faster
Added a warning that `.find().filter()` may be faster on non-branchy structures
Latest commit 3014886 May 2, 2014
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
CHANGELOG.md
LICENSE Initial commit Apr 16, 2014
README.md
bower.json Version bump to 0.1.1 Apr 16, 2014
jquery.closestchild.js Version bump to 0.1.1 Apr 16, 2014

README.md

jquery-closestchild

An opposite of closest(): find the nearest child that matches a selector, ignore deeper matching children.

What this plugin is for

Let's say you've got an HTML module like this:

<div class="module">
  module
  <div class="module-title">title</div>
  <div class="module-foo">
    foo
    <div class="module-bar">bar</div>
  </div>
  <div class="module-children">
  </div>
</div>

These modules can nest into each other in a tree-like fashion:

<div class="module" id="module1">
  module
  <div class="module-title">title</div>
  <div class="module-foo">
    foo
    <div class="module-bar" id="module1bar">bar</div>
  </div>
  <div class="module-children">
  
    <div class="module" id="module2">
      module
      <div class="module-title">title</div>
      <div class="module-foo">
        foo
        <div class="module-bar">bar</div>
      </div>
      <div class="module-children">
      
        <div class="module" id="module3">
          module
          <div class="module-title">title</div>
          <div class="module-foo">
            foo
            <div class="module-bar">bar</div>
          </div>
          <div class="module-children">
          
          </div>
        </div>
        
      </div>
    </div>
    
    <div class="module" id="module4">
      module
      <div class="module-title">title</div>
      <div class="module-foo">
        foo
        <div class="module-bar">bar</div>
      </div>
      <div class="module-children">
      
      </div>
    </div>

  </div>
</div>

Now, for any given module you would like to select an .module-foo element that belongs to that module. But you don't want to include .module-foos of any child modules!

jQuery provides a .closest() method that selects the nearest parent that matches a criteria. If only there were a similar method that selects the nearest child...

Well, now there is! $('#foo').closestChild('.module-bar') will select only one element: the #module1bar from the example above.

Installation

Require jquery.closestchild after jQuery:

<script src="/jquery.js"></script>
<script src="/jquery.closestchild.js"></script>

Usage

$('.some-element').closestChild( selector )

Note that there's capital C in the middle of method name, while file and project names are all lowercase.

selector can be anything that the jQuery .filter() method uses.

closestChild returns a jQuery collection of matched elements.

Please keep in mind the following features:

  • It starts matching with the children of the given element (unlike .closest() which starts matching with the element itself).
  • It traverses the tree of children one step at a time. It can return multpile elements if they are found on the same level of depth.
  • Once at least one match is found, it returns the match(es) and stops traversing, saving performance.

This behavior is different from jquery-nearest which would traverse each branch of the DOM tree as deep as it goes. jquery-nearest only prevents traversing inside matched elements.

Demo

See jquery.closestchild in action:

Performance

Here's a straighforward way of selecting the closest child (suggested by adeneo on StackOverflow):

var $parent = $('.some-element');
$parent.find('.child').filter(function() {
  return $(this).closest('.some-element').get(0) === $parent.get(0);
});

Here's a performance comparison of this method against jquery-closestchild: http://jsperf.com/closestchild#runner . jquery-closest child turns out to be 4 to 5 times faster in this benchmark. The difference in speed is proportional to the depth and branchiness of the DOM tree.

Note, that if your HTML structure is not branchy (e. g. <div> <div> <div> </div> </div> </div>), the .find().filter() may appear faster.

Also note that pure .find() without filtering always performs much faster. If you don't need to filter out deeper children, you should prefer .find() over .closestChild() even if you know that the sought element is near the start of the tree. That's because pure .find() leverages browser optimizations whereas .closestChild() traverses the tree step by step. In other words, never use .closestChild() where .find() without filtering can do the job.

Credit

Created by Andrey Mikhaylov aka lolmaus.

Thanks to adeneo from StackOverflow.

Sponsored by Hivemind, a knowledge base SaaS solution for your business.

License

MIT License.

You can’t perform that action at this time.