Обход Javascript и извлечение родительского дерева на основе родительских атрибутов

89
9

У меня есть меню. Я хотел бы получить дерево любого выбранного выбранного элемента.

<ul>
<li>
<a>Deserts</a>
<ul class="category">
<li data-parent="Deserts">
<a>Cakes</a>
<ul class="sub-category">
<li data-parent="Cakes">
<a>Fruit</a>
<ul class="sub-category">
<li data-parent="Fruit">
<a>Jelly</a>
</li>
<li data-parent="Fruit">
<a>Puree</a>
</li>
<li data-parent="Fruit">
<a>Concentrate</a>
</li>
</ul>
</li>
</ui>
</li>
</ui>
</li>
</ul>

Поэтому, если пользователь нажал на Jelly. Это вернет что-то вроде: Cakes/Fruit/Jelly.

Как я могу получить дерево щелкнутого элемента? .parentsUntil() ли .parentsUntil()?

$("a").click(function () {
alert($(this).parentsUntil('.category').data('parent'));
});

спросил(а) 2021-01-25T15:44:01+03:00 4 месяца, 4 недели назад
1
Решение
78

Вы были на правильном пути. data('parent') возвращает только первый атрибут, поэтому вам нужно использовать jQuery#map (а также отфильтровать родителей, чтобы включить только li).

Ниже приведена демонстрация того, как вы можете получить массив всех категорий, к которым принадлежит данный элемент. Это не относится к самому элементу (например, "Желе"), но я добавлю несколько предложений о том, как исправить эту проблему.

(Кроме того, как указано в комментариях выше, вы должны использовать теги </ul> а не </ui>).

$("a").click(function () {
var categories = $(this).parentsUntil('.category', 'li').map(function (i, e) {
return e.getAttribute('data-parent')
}).toArray().reverse()
console.log(categories.join('/'))
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li>
<a>Deserts</a>
<ul class="category">
<li data-parent="Deserts">
<a>Cakes</a>
<ul class="sub-category">
<li data-parent="Cakes">
<a>Fruit</a>
<ul class="sub-category">
<li data-parent="Fruit">
<a>Jelly</a>
</li>
<li data-parent="Fruit">
<a>Puree</a>
</li>
<li data-parent="Fruit">
<a>Concentrate</a>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>

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

Вместо использования data-parent и ссылки на одну и ту же информацию по каждому элементу категории (например, data-parent="fruit"), вы должны определить атрибут data-name который существует в li независимо от того, представляют ли они элемент или категорию, Ваша верхняя ul, которая содержит каждую категорию и подкатегорию, может быть помечена как .categories чтобы отличить ее от других ul. Я думаю, что код будет говорить лучше, чем здесь, поэтому я включил пример реализации. Посмотрите, как реструктурируется HTML и как это упрощает код jQuery.

$("a").click(function() {
var names = $(this).parentsUntil('.categories', 'li').map(function(i, e) {
return e.getAttribute('data-name')
}).toArray().reverse()
console.log(names.join('/'))
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="categories">
<li class="category" data-name="Deserts">
<a>Deserts</a>
<ul>
<li class="category" data-name="Cakes">
<a>Cakes</a>
<ul>
<li class="category" data-name="Fruit">
<a>Fruit</a>
<ul>
<li class="item" data-name="Jelly">
<a>Jelly</a>
</li>
<li class="item" data-name="Puree">
<a>Puree</a>
</li>
<li class="item" data-name="Concentrate">
<a>Concentrate</a>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>

ответил(а) 2021-01-25T15:44:01+03:00 4 месяца, 4 недели назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема