Учитывая эту демонстрационную разметку (принимающий случайное число элементов между .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;
});
});
Я на правильном пути там? Это не работает так, я предполагаю, что у меня есть определенная логическая ошибка все еще.
Вот еще вариант. Предположим, у вас есть .outer
o
, это выберет все внутренние
под ним:
o.find('.inner').not(o.find('.outer .inner'))
Он должен работать так же, как ответ gnarf, но немного проще.
Сначала он находит все внутренние
под этим внешним
.
Затем удалите все внутренние
, которые являются потомками других внешних
Интерактивный рабочий пример: http://jsfiddle.net/Zb9gF/
Производительность селектора кажется намного лучше используя этот метод вместо .filter ()
: http://jsperf.com/selector-test-find-not
Если .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');
$('.outer').children('.inner');
Это выберет любой внутренний
, который находится непосредственно под внешним
. Я не совсем понимаю, какой div вы пытаетесь выбрать. Это a, b, c или d? Наличие чего-то, что называется внешним, вложенным в нечто, называемое внутренним, не имеет большого смысла. Может быть, вы могли бы привести более конкретный пример?
Если правильно предположить, вы хотите выбрать все . inner
, которые находятся под .outer
, за исключением случаев, когда между ними есть .outer
, возможно, будет работать следующее (не проверено):
$('.outer:not(.inner):has(:not(.outer) .inner:not(.outer), > .inner:not(.outer))');
обновлено после проверки на примере OP HTML на http://jsfiddle.net/cEwBT/1/
Вы можете использовать некоторую магию css:
$('.outer>.inner')
Shold дает вам только первый уровень элементов .inner
. :)
Интересно, почему бы сначала не выбрать .inner
, а затем получить ближайший
.outer
?
$inner = $('.inner'); $outer = $inner.closest('.outer');
в случае, если некоторые внутренние блоки могут быть не во внешних блоках вообще, используйте эту первую строку вместо
$ inner = $ ('. outer .inner');