Skip to content

Latest commit

 

History

History
155 lines (103 loc) · 4.83 KB

README.md

File metadata and controls

155 lines (103 loc) · 4.83 KB

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.