#jquery #jquery-selectors
#jquery #jquery-селекторы
Вопрос:
У меня есть следующая структура :
<ul>
<li><a>link</a>
<ul>
<li>
<a>link</a>
<ul>
<li><a>link</a></li>
<li><a>link</a></li>
<li><a>link</a></li>
</ul>
</li>
<li>
<a>link</a>
<ul>
<li><a>link</a></li>
<li><a>link</a></li>
<li><a>link</a></li>
</ul>
</li>
</ul>
</li>
<li>
<div>content
<ul>
<li><a>link</a></li>
<li><a>link</a></li>
<li><a>link</a></li>
</ul>
</div>
</li>
<li><a>link</a></li>
<li><a>link</a></li>
<li><a>link</a></li>
</ul>
Я хочу выбрать только якоря, которые попадают непосредственно под <li>
теги (дочерние элементы), но не те, которые попадают под другие теги (внуки)
если я сделаю
$('ul li> a')
Я также получу ul, который вложен под div. есть ли «чистый» способ сделать это?
Спасибо
ps: Я хотел бы иметь универсальный селектор (это для плагина меню, поэтому я хочу, чтобы он игнорировал все теги привязки, которые не попадают непосредственно в поток меню)
Комментарии:
1. Можете ли вы добавить идентификатор к корню,
ul
чтобы отличить его от любогоul
? Тогда$('#root > li > a')
не будет хватать это глубжеul > li > a
. Или вы также хотите, чтобы были захвачены другие deepul > li > a
s, только не тот, который находится подdiv
?2. да, это возможно, однако я хочу использовать это в плагине, поэтому селектор должен быть менее строгим.
3. Итак, вы хотите захватить все
a
элементы на любой глубине, если их предками являются толькоul
илиli
? Итак,ul > li > a
будет совпадать, иul > li > ul > li > ul > li > a
тоже будет совпадать?4. да, но в этом случае ul> li> div> ul> li> a также соответствовал бы, не так ли?
5. @wiseguy, да, точно … он не должен соответствовать ничему ПОД div (или чему-либо другому, кроме ul или li)
Ответ №1:
Окончательное решение
Этот ответ был полностью отредактирован, чтобы поддерживать его в актуальном состоянии. Конечное решение — это, по сути, селектор, в котором, начиная с идентификатора исходного <ul>
элемента, выберите все привязки в элементах списка, что не нарушает поток структуры меню. То есть, если есть элемент, отличный от <ul>
или <li>
вложенного внутри, не выбирайте ничего внутри этих элементов, даже если внутри есть меню.
Результирующий селектор ( #root
является идентификатором основного <ul>
) :
$('#root > li > a, #root ul:not(#root :not(ul,li) ul) > li > a')
Вы можете попробовать демо-версию здесь: http://jsfiddle.net/9gPzQ/31 /
Однако оригинальный постер @salmane хотел сделать это для плагина, который уже поставляется с переданным элементом, поэтому он придумал следующий код, чтобы сделать то же самое, что и выше, но внутри уже выбранных объектов, переданных в качестве контекста селектора:
$('li >a',this.content).not($(':not(ul,li) a',this.content))
Другие интересные селекторы
На пути поиска решения возникли некоторые интересные селекторы из-за моего непонимания проблемы, но я все равно включу их сюда просто для справки, кому-то это может пригодиться. 🙂
Этот селектор выбирает привязки элементов списка, которые находятся на верхнем уровне меню, где бы они ни находились на странице:
$(':not(li) > ul > li > a')
Этот селектор выбирает привязки элементов списка, которые находятся на верхнем уровне меню, игнорируя меню, вложенные в другие меню, даже если они вложены в другие контейнеры:
$('ul:not(ul ul) > li > a')
Вы можете попробовать эти селекторы в демо-версии здесь: http://jsfiddle.net/9gPzQ/4 /
Комментарии:
1. 1 Хорошее решение. Производительность должна быть в порядке, поскольку выбор обычно выполняется справа налево, поэтому нет необходимости в дорогостоящем
*
вызове где бы то ни было.2. на самом деле это звучит близко, но что-то, что выбирало бы только ul> li> a, которые попадают непосредственно под li .. ваше предложение делает прямо противоположное, или я ошибаюсь?
3. итак, я предполагаю, что это сработает, если я сделаю: (‘li > a’).not(‘:not(li) > ul > li > a’)… Я должен попробовать… @lonesomeday я надеюсь, что ваша оценка производительности остается в силе 🙂
4. Потребовалось немного повозиться, но вот как это выглядит при использовании объекта: $(‘li >a’,this.content).not($(‘:not(ul, li) a’,this.content)) Еще раз спасибо @DarthJDG за вашу помощь 🙂
5. Это действительно хорошее решение. Это было весело.
Ответ №2:
Я думаю, что вы ищете:
$('ul:parent ul li>a')
Это даст вам все li>a
без div или чего-либо в нем.
Ответ №3:
Благодаря замечательному вкладу @DarthJDG
это решение
$('li >a',this.content).not($(':not(ul,li) a',this.content))
this.content является объектом, на который ссылается подключение, в данном случае объект является родительским UL
Я надеюсь, что это кому-то поможет