最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - jQuery find which parent is closer? - Stack Overflow

programmeradmin0浏览0评论

In jQuery you can call closest to find the closest parent.

If I have a a in a li in a ul in a td in a table. I want to find out if the ul parent is closer than the table parent. Obviously in this case the answer is obvious.

If I run $('a').closest('table').length or $('a').closest('ul').length both return 1.

I would like to find out which parent is closer in the DOM.

Technically if there were a method than in this case $('a').closer('ul', 'table') would return the ul because it is closer in the DOM.

<table> <!-- Is this closer -->
    <tr>
        <td>
            <ul> <!-- Or is this closer -->
                <li>
                    <a href="#">A button</a>
                </li>
            </ul>
        </td>
    </tr>
</table>

In jQuery you can call closest to find the closest parent.

If I have a a in a li in a ul in a td in a table. I want to find out if the ul parent is closer than the table parent. Obviously in this case the answer is obvious.

If I run $('a').closest('table').length or $('a').closest('ul').length both return 1.

I would like to find out which parent is closer in the DOM.

Technically if there were a method than in this case $('a').closer('ul', 'table') would return the ul because it is closer in the DOM.

<table> <!-- Is this closer -->
    <tr>
        <td>
            <ul> <!-- Or is this closer -->
                <li>
                    <a href="#">A button</a>
                </li>
            </ul>
        </td>
    </tr>
</table>
Share Improve this question edited Mar 6, 2016 at 23:49 Johnston asked Mar 6, 2016 at 23:40 JohnstonJohnston 20.9k22 gold badges75 silver badges124 bronze badges 4
  • 1 I think you should post a snippet of the HTML that you are referring to. It will make things clearer to everyone. – bob.mazzo Commented Mar 6, 2016 at 23:45
  • 1 1. As bob has mentioned, HTML is needed to determine position and relation of the elements/nodes within the DOM. 2. All elements (except the root which is <html> has only one parent. How can an element have more than one parent? What you mean is ancestors. – zer00ne Commented Mar 6, 2016 at 23:51
  • @zer00ne: It's jQuery's fault: the function to get all ancestors is called .parents(). – Amadan Commented Mar 6, 2016 at 23:54
  • @Amadan I guess .ancestors() would be too verbose. – zer00ne Commented Mar 6, 2016 at 23:56
Add a ment  | 

5 Answers 5

Reset to default 6

You can list multiple element selectors to the closest function, it will only find the closest of one of them:

$('a').closest('table, ul')

Example:

$(document).on("click", function( event ) {
  $(event.target).closest("li, b").toggleClass("hilight");
});
.hilight{
  background: rgba(255, 0, 0, 0.5);
}
<script src="https://ajax.googleapis./ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
  <li><b>Click me!</b></li>
  <li>You can also click this line <b>or click me!</b></li>
</ul>

Use .parents(). It returns a list of all parents that are ordered from closest to farthest.

The difference between using this and using .closest(selector) is that it accepts a jQuery object instead of a selector string, which has to be hard coded. Meanwhile jQuery objects can be collections and so can be generated on the fly.

(function($) {
  $.fn.getClosest = function(testElements) {
    var element = $(this);
    var parents = element.parents();
    var indexClosest = Number.MAX_VALUE;
    testElements.each(function() {
      var index = parents.index($(this));
      if (index > -1 && index < indexClosest)
        indexClosest = index;
    });
    return parents.eq(indexClosest);
  };
})(jQuery);

Use the function like this:

$("a").getClosest($("table, ul"))

Fiddle with advanced use case

I like Fabian's answer; but to actually measure the distance, you can use this:

var $parentsUntilTable = $('li').parentsUntil('table');
var $parentsUntilUl = $('li').parentsUntil('ul');
console.log($parentsUntilTable.length < $parentsUntilUl.length
           ? 'table is closer'
           : 'ul is closer');
<!-- results pane console output; see http://meta.stackexchange./a/242491 -->
<script src="http://gh-canon.github.io/stack-snippet-console/console.min.js"></script>

<script src="https://ajax.googleapis./ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<table>
  <tr>
    <td>
      <ul>
        <li>
        </li>
      </ul>
    </td>
  </tr>
</table>

Here is a simple implementation of the .closer() method that returns the selector that is closest to the given element:

$.fn.closer = function(varargs) {
  var $elem = $(this);
  while ($elem.length) {
    for (var i = 0, len = arguments.length; i < len; i++) {
      if ($elem.is(arguments[i])) {
        return arguments[i];
      }
    }
    $elem = $elem.parent();
  }
  return null;
};

See it in action on jsFiddle.

An element only has one parent node, above those are ancestor nodes.

From here: https://stackoverflow./a/15149590/1876047 - you can use

$(elem1).offset().top - $(elem2).offset.().top

As both nodes are ancestors of the element you are considering, the one furthest from the root of the DOM tree is the closet to your element.

So if the above difference is greater than 0, then elem2 is closest, otherwise elem1 is closest.

发布评论

评论列表(0)

  1. 暂无评论