#javascript #jquery #css
#javascript #jquery #css
Вопрос:
Итак, вот как выглядит мое DOM-дерево:
<div id="content">
<div id="sidebar">
<ul>
<li class="selected"><a href="#">Header 1</a>
<ul>
<li><a href="#">Link 1</a></li>
<li><a href="#">Link 2</a></li>
<li><a href="#">Link 3</a></li>
<li><a href="#">Link 4</a></li>
</ul>
</li>
<li><a href="#">Header 2</a>
<ul>
<li><a href="#">Link 1</a></li>
<li><a href="#">Link 2</a></li>
</ul>
</li>
<li><a href="#">Header 3</a>
<ul>
<li><a href="#">Link 1</a></li>
<li><a href="#">Link 2</a></li>
</ul>
</li>
<li><a href="#">Header 7</a>
<ul>
</ul>
</li>
<li><a href="#">Header 4</a>
<ul>
</ul>
</li>
<li><a href="#">Header 5</a>
<ul>
<li><a href="#">Link 1</a></li>
</ul>
</li>
</ul>
</div>
</div>
Итак, когда я хочу выполнить простое addClass
и removeClass
для одного элемента, это работает:
$(document).ready(function() {
$('div#content div#sidebar ul li a').click(function(e) {
if ($(this).parent().hasClass('selected')) {
$(this).parent().removeClass('selected');
}
else {
$(this).parent().addClass('selected');
}
e.preventDefault();
});
});
Однако это не удаляет класс selected
из каждого «однорангового узла» $(this).parent()
. Он удаляет класс только из родительского элемента выбранного в данный момент элемента.
Что я хочу сделать, так это то, что при нажатии на ссылку Header 2
, она добавляет класс selected
в Header 2
и проверяет все родственные элементы (в данном случае, li
s для ссылок Header 1 - 7
) и удаляет этот класс для любых родственных элементов, если он его находит. Таким образом, по сути, на этом уровне в DOM-дереве может быть только один класс selected
.
Как мне это сделать?
Ответ №1:
$(function () {
$('#sidebar > ul > li > a').bind('click', function (e) {
e.preventDefault();
$('#sidebar > ul > li').removeClass('selected');
$(this).parent().addClass('selected');
});
});
При этом выбираются <a>
элементы, вложенные в первый уровень <li>
элементов, и добавляется .selected
класс к его родительскому <li>
элементу (при одновременном удалении всех других экземпляров .selected
класса).
Вот jsfiddle:http://jsfiddle.net/jasper/RRk25
Это можно было бы оптимизировать:
$(function () {
var $first_tier_li = $('#sidebar > ul > li');
$first_tier_li.children('a').bind('click', function (e) {
e.preventDefault();
$first_tier_li.removeClass('selected');
$(this).parent().addClass('selected');
});
});
Это экономит поиск узлов DOM при каждом нажатии, поскольку они кэшируются с момента возникновения document.ready
события.
Вот jsfiddle оптимизации:http://jsfiddle.net/jasper/RRk25/1
Комментарии:
1. Эй, @ Jasper, ты не возражаешь отредактировать это так, чтобы дочерние
ul
элементы элемента, которые будут удалены, исчезли, или scrollUp, или исчезнут навсегда… в то время как другой показывает себя. Нужно ли мне добавить немного CSS, чтобы получить это, или я могу сделать все это в jQuery?2. Та правка, которую вы включили об оптимизации, имеет полный смысл, потому что я хочу манипулировать
second_tier
, так что вы заложили основу для того, чтобы иметь возможность это делать … и это потрясающе.3. jsfiddle.net/jasper/RRk25/2 , вот так. При этом используются функции
.slideUp()
и.slideDown()
для отображения / скрытия дочерних<ul>
элементов. Обратите внимание, что я добавил объявление CSS, чтобы скрыть все<ul>
теги второго уровня при загрузке (но я также добавил встроенный CSS в первый «вспомогательный навигатор»,<ul>
поэтому он отображается по умолчанию).
Ответ №2:
Удалите класс из всех элементов $ (‘div#content div#sidebar ul li’), а затем просто добавьте класс к выбранному. Это сработает для вас?
Смотрите это здесь
Комментарии:
1. Смотрите мою новую правку. Теперь я не уверен, что бы вы хотели делать, когда пользователи нажимают на не заголовки, но это все.