jQuery, фильтрующий селектор для удаления вложенные элементы, соответствующие шаблону

Учитывая эту демонстрационную разметку (принимающий случайное число элементов между .outer и .inner:

<div class="outer">
    <div>
        <div>
            <div class="inner"></div>
        </div>
    </div>
</div>

Я могу настроить jQuery для выбора внешних и внутренних отделений как таковых:

$outer = $('.outer');
$inner = $outer.find('.inner')

Хорошо работает.

Однако скажем, я хочу позволить неограниченное вложение этой логики, таким образом, у меня может быть это:

<div class="outer"> div a
    <div class="inner"> div b
        <div class="outer"> div c
            <div class="inner"> div d </div>
        </div>
    </div>
</div>

В той ситуации, при выборе отделения через .outer Я хочу соответствовать ему только отделению b. В otherwords я хочу исключить предков вложенного .outer предок.

Я хотел бы иметь сокращения внешних и внутренних (s), содержавший на их уровне вложенности.

Я надеюсь .filter() мог осуществить его, но не может думать о селекторе, который работал бы универсально на неограниченные вложенные шаблоны. Это - выполнимое использование фильтра? Или возможно даже прямой селекторный шаблон?

ОБНОВЛЕНИЕ:

Я думаю, что что-то вроде этого могло работать, но не уверенное, как каждый может (или если это позволяется), ссылаются на 'это' в селекторе:

$outer = $('.outer');
$inner = $outer.not('this .outer').find('.inner')

ОБНОВЛЕНИЕ 2:

Я должен был упомянуть это первоначально: .inner всегда будет потомок .outer но не обязательно непосредственный ребенок.

ОБНОВЛЕНИЕ 3:

Вот некоторые испытательные образцы HTML, который мог использоваться. В каждом случае я хотел бы смочь выбрать .outer и разделить на пары .inner's, который он содержит между собой и вложенным внешним. Для ясности я добавил имена к каждому отделению (внешние-x пары с внутренним-x)

//sample 1
<div class="outer"> outer-a
    <div>
        <div class="inner"> inner-a
            <div class="outer"> inner-b
                <div class="inner"> inner-b </div>
            </div>
        </div>
    </div>
    <div>
        <div class="inner"> inner-a </div>
    </div>
</div>

//sample 2
<div class="outer"> outer-a
        <div class="inner"> inner-a
            <div class="outer"> inner-b
                <div>
                    <div class="inner"> inner-b </div>
                </div>
            </div>
        </div>
</div>

//sample 3
<div class="outer"> outer-a
        <div class="inner"> inner-a
            <div class="outer"> inner-b
                <div class="inner"> inner-b
                    <div class="outer"> outer-c 
                        <div class="inner"> inner-c</div>
                    </div>
                </div>
            </div>
        </div>
</div>

//bonus sample (we're trying to avoid this)
<div class="outer"> outer-a
        <div class="inner outer"> inner-a outer-b
            <div class="inner"> inner-b </div>
        </div>
</div>

ОБНОВЛЕНИЕ 4

Я думаю, что закончил тем, что спустился по подобному пути как gnarf. Я закончил с этим:

var $outer = $('.outer');
var $inner = $outer.find('.inner').filter(function(){
    $(this).each(function(){
        return $(this).closest('.outer') == $outer; 
  });                                                                  
});

Я на правильном пути там? Это не работает так, я предполагаю, что у меня есть определенная логическая ошибка все еще.

6
задан DA. 22 June 2010 в 20:56
поделиться

6 ответов

Вот еще вариант. Предположим, у вас есть .outer o , это выберет все внутренние под ним:

o.find('.inner').not(o.find('.outer .inner'))

Он должен работать так же, как ответ gnarf, но немного проще.

Сначала он находит все внутренние под этим внешним .
Затем удалите все внутренние , которые являются потомками других внешних

Интерактивный рабочий пример: http://jsfiddle.net/Zb9gF/

Производительность селектора кажется намного лучше используя этот метод вместо .filter () : http://jsperf.com/selector-test-find-not

12
ответ дан 8 December 2019 в 14:40
поделиться

Если .inner всегда являются прямыми дочерними элементами .outer ] s - children () , вероятно, ваш лучший выбор (ответ jasongetsdown)

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

var $outer = $('.outer').first(); // grab the first .outer
$outer.find('.inner').filter(function() {
    // only if the closest parent .outer is the same as the .outer we are looking in
    return $(this).closest('.outer').get(0) == $outer.get(0);
}).css('border','1px solid #000');

jsfiddle demo

2
ответ дан 8 December 2019 в 14:40
поделиться
$('.outer').children('.inner');

Это выберет любой внутренний , который находится непосредственно под внешним . Я не совсем понимаю, какой div вы пытаетесь выбрать. Это a, b, c или d? Наличие чего-то, что называется внешним, вложенным в нечто, называемое внутренним, не имеет большого смысла. Может быть, вы могли бы привести более конкретный пример?

1
ответ дан 8 December 2019 в 14:40
поделиться

Если правильно предположить, вы хотите выбрать все . inner, которые находятся под .outer, за исключением случаев, когда между ними есть .outer, возможно, будет работать следующее (не проверено):

$('.outer:not(.inner):has(:not(.outer) .inner:not(.outer), > .inner:not(.outer))');

обновлено после проверки на примере OP HTML на http://jsfiddle.net/cEwBT/1/

1
ответ дан 8 December 2019 в 14:40
поделиться

Вы можете использовать некоторую магию css:

$('.outer>.inner')

Shold дает вам только первый уровень элементов .inner . :)

0
ответ дан 8 December 2019 в 14:40
поделиться

Интересно, почему бы сначала не выбрать .inner , а затем получить ближайший .outer ?

$inner = $('.inner');
$outer = $inner.closest('.outer');

в случае, если некоторые внутренние блоки могут быть не во внешних блоках вообще, используйте эту первую строку вместо

$ inner = $ ('. outer .inner');

0
ответ дан 8 December 2019 в 14:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: