#javascript #jquery
#javascript #jquery
Вопрос:
У меня есть некоторый html, где элементы вложены для создания эффекта аккордеона. Что-то похожее на:
<span class="container">
<div class="item">1</div>
<span class="container">
<div class="item">1.a</div>
<span class="container">
<div class="item">1.a.1</div>
</span>
</span>
</span>
Мне нужно использовать $('.container').find('.item').each()
для создания иерархии, в которой 1.a становится дочерним элементом 1, а 1.a.1 становится дочерним элементом 1.a. Проблема, с которой я сталкиваюсь, заключается в том, что 1.a.1 также становится дочерним элементом 1, потому что 1.a.1 является потомком 1.
Теоретически также может быть 1.b или 1.c и т.д. поэтому мне нужно найти всех потомков, а не только первого, но я не хочу находить потомков потомков.
Есть ли простой способ jQuery сделать это?
.children() не работает для моего конкретного случая, потому что в реальном HTML, в котором я нахожусь, больше вложенных контейнеров и еще много чего.
Комментарии:
1. Вы можете использовать
children('.item')
илиfind('> .item')
, однако ваш первый селектор будет возвращать все контейнеры, включая вложенные. Таким образом, при отключении такого глобального селектора вы все равно будете возвращать все элементы.2. Вы могли
$('.container').first()
бы получить только верхний контейнер, прежде чем получать только его вложенные элементы.3. @Taplar Я должен был упомянуть об этом, но причина, по которой я использую .find() вместо .children(), заключается в том, что в моем HTML элементы .item не являются прямыми дочерними элементами элементов .container . Я написал макет HTML, поэтому я не вставлял 50 строк, которые, как я ошибочно полагал, были неактуальными.
4. Затем вам нужно будет выбрать конкретный контейнер, найти вложенные элементы, а затем отфильтровать те, чей ближайший контейнер не является нужным контейнером.
5. Вы ищете что-то в строках этого ?
Ответ №1:
Я написал функциональность здесь. Идея в том, что вы ищете всех потомков с item
классом. Затем вы удаляете все те элементы из списка, которые имеют предка с item
классом. Этот предок все равно должен быть потомком контейнера (или начальной точки вашего элемента).
var container = $('.container');
var descendants = container.find('.item');
var res = [];
descendants.each(function() {
let parents = $(this).parents();
for (let i = 0; i < parents.length; i ) {
//console.log('p: ' $(parents[i]).text());
if (container.html() == $(parents[i]).html()) {
//no ancestors with the `item` class found, this is a good one.
res.push($(this));
break;
}
if ($(parents[i]).hasClass('item')) {
//if an ancestor with the same class has been found
//it cannot be kept
break;
}
}
});
console.log(descendants);
console.log(res);
Я создал скрипку для тестирования
Комментарии:
1.
$(parents[i])
является анти-шаблоном. Вы удаляете элемент из стека результатов jQuery, а затем создаете новый объект jQuery только с одним элементом. Используйте.eq(i)
, чтобы избежать этого.2. Также вместо того, чтобы создавать скрипку вне сайта, чтобы показывать рабочий код, создайте исполняемый фрагмент на сайте .