Как выбрать «самого мелкого» подходящего потомка? - PullRequest
7 голосов
/ 13 августа 2011

Как я могу выбрать первый «самый мелкий» вход?

Моим текущим выбором будет div, помеченный как «выбранный».
Я не буду знать, сколько уровней будет ниже.*

<div class="selected"> <!-- already have this -->
  <div class="unknown-number-of-wrapper-panels">
    ...
    <div class="collection">    
      <div class="child">
        <input type="text" value="2" /> <!-- don't want this -->
      </div>
    </div>
    <input type="text" value="2" /> <!-- need this -->
    <input type="text" value="2" />
    ...
  </div>
</div>

Кажется, что find().first() дает мне самый глубокий.

Отредактировано для ясности.Мне нужно найти его, основываясь на том факте, что он более мелкий, а не на других уникальных атрибутах.

Это может быть похоже на обратную сторону closest()?

Ответы [ 6 ]

7 голосов
/ 13 августа 2011

Если я понимаю вашу проблему, вам нужно рекурсивно проверить дочерние узлы на наличие элементов с этим классом.

function findShallowest( root, sel ) {
    var children = root.children();
    if( children.length ) {
        var matching = children.filter( sel );
        if( matching.length ) {
            return matching.first();
        } else {
            return findShallowest( children, sel );
        }
    } else {
        return null;
    }
}

var selected = $('.selected');

findShallowest( selected, ':text' );

Пример: http://jsfiddle.net/Qf2GM/


EDIT: Забыл оператор возврата и имел селектор идентификатора вместо селектора класса для начального .selected.


Или создайте собственный плагин:

Пример: http://jsfiddle.net/qX94u/

(function($) {
    $.fn.findShallowest = function( sel) {
        return findShallowest( this, sel );
    };
    function findShallowest(root, sel) {
        var children = root.children();
        if (children.length) {
            var matching = children.filter(sel);
            if (matching.length) {
                return matching.first();
            } else {
                return findShallowest(children, sel);
            }
        } else {
            return $();
        }
    }
})(jQuery);

var result = $('.selected').findShallowest( ':text' );


alert( result.val() );
3 голосов
/ 17 сентября 2012

Просто чтобы немного поиграть в этот «плагин» - используется техника @ user113716 , только уменьшенный размер кода.

$.fn.findShallowest = function( selector ) {
    var children = this.children(),
        matching = children.filter( selector );
    // return an empty set if there are no more children
    if ( !children.length ) {
        return children;
    }
    // if anything matches, return the first.
    if ( matching.length ) {
        return matching.first();
    }
    // check grand-children
    return children.findShallowest( selector );
};

Примерь jsFiddle

3 голосов
/ 13 августа 2011

Вы ищете поиск в ширину, а не поиск в глубину (который использует jQuery's find ()).Быстрый Google нашел: http://plugins.jquery.com/project/closestChild

Это может быть использовано так:

$(...).closestChild('input')
1 голос
/ 13 августа 2011

Это другой подход. Идея в том, что вы получите соответствующий элемент с наименьшим количеством предков:

(function($) {
    $.fn.nearest = function(selector) {
        var $result = $();
        this.each(function() {
            var min = null,
                mins = {};
            $(this).find(selector).each(function() {
                var n_parents = $(this).parents().length,                
                if(!mins[n_parents]) {
                     mins[n_parents] = this;
                     min = (min === null || n_parents < min) ? n_parents : min;
                }              
             });
             $result = $result.add(mins[min]);
       });

       return $result;
    };
}(jQuery));

Использование:

$('selected').nearest('input');

ДЕМО

findShallowest, как у @patrick , может быть лучшим именем метода;)

0 голосов
/ 13 августа 2011

Хорошо, учитывая вашу разметку, будет ли работать следующее?

$('.selected div > input:first')
0 голосов
/ 13 августа 2011

Если вы не знаете имя класса нижнего уровня элемента , вы всегда можете использовать что-то вроде

$('.unknown-number-of-wrapper-panels').children().last();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...