Помогите с раскрытием списка - JS

12
V
На сайте с 10.01.2012
Offline
85
1105

возникла надобность переделать многоуровневое вертикальное меню так чтобы, если в нем есть подуровень, при нажатии на элемент ссылка не срабатывала а открывался вложенный список.

Пытался реализовать таким образом


$('.menu-v li').bind('click',function(event){
event.preventDefault();

if ($(this).find('ul')) { //если в нажатом элементе есть вложенный список

list_item=$(this).find('ul:first'); // берем его в обработку


if (list_item.css('display')=='none') { // и заскрываем/скрываем в зависимости от состояния
list_item.css('display','block');
}
else {
list_item.css('display','none');
}

}
else {
alert("error");

}
});

Загвоздка в том, что данная конструкция срабатывает только для первого уровня. При назатии на раскрытие второго уровня он то раскрывается, но сразу же и скрывается первый.

Где я допустил ошибку, чтобы при клике обрабатывался только текущий элемент а не и дочерние.

+ событие алерт никогда не срабатывает. даже если в нажатом элементе нет вложенного списка.

Заранее благодарю за ответ

Оптимизайка
На сайте с 11.03.2012
Offline
396
#1


if ($(this).find('ul'))

find всегда будет возвращать объект jQuery, т.е. это условие всегда истинно. Наверное, вы хотели всё же if ($(this).find('ul').length)

⭐ BotGuard (https://botguard.net) ⭐ — защита вашего сайта от вредоносных ботов, воровства контента, клонирования, спама и хакерских атак!
V
На сайте с 10.01.2012
Offline
85
#2

Спасибо. не учел этот момент на проверку существования. Данный вопрос отпал, но основной все же остался

[Удален]
#3

Varenik, я бы для проверки использовал бы что-то типа

if($(this).children('ul:visible').size()<1)

а для переключения

$(this).toggleClass('нужный класс');
V
На сайте с 10.01.2012
Offline
85
#4
burunduk:
Varenik, я бы для проверки использовал бы что-то типа

а для переключения

использование класса или назначение стилей на прямую - не столь существенно в данном случае. Проблема в том что, если есть структура:


<li class="cl_1"><a href="#">Для детей</a>
<ul id="id_1">
<li class="cl_2"><a href="#">Постельное белье</a>
<ul id="id_2">
<li>kjhkjhl</li>
<li>nk,n,n,n</li>
</ul>
</li>
</ul>
</li>

при нажатии на cl_1 раскрывается id_1. при нажатии на cl_2 должен раскрывается id_2. На практике он и раскрывается, но тут же срабатывает скрытие id_1, что не должно происходить

[Удален]
#5

Varenik, ну во первых сама структура не совсем корректна, точнее проблема в <a href="#">

это в принципе лишние, если переход не нужен, то и тег <a> там лишний, событие клик можно обрабатывать на любом элементе, а вот разобраться со открытием/скрытием нескольких уровней, наличие/отсутствие тега <a> может помочь ;)

V
На сайте с 10.01.2012
Offline
85
#6

Структура правильная и исходя с нее и нужно плясать. Переписал код и привел его к вот такому виду и все работает

$('document').ready(function(){

$('.menu-v li').click(function (event) {

if ($(this).find('ul').length) {


event.preventDefault();
$(this).parent().find("li ul:visible").slideUp();


if($(this).children("ul").is(":hidden")) {
$(this).children("ul").slideDown() ;

}
event.stopPropagation();
}

});


});

Но теперь постал вопрос о маркировке активного пункта, который нажат и скрытие остального. Голова уже квадратная

[Удален]
#7
Varenik:
Но теперь постал вопрос о маркировке активного пункта
$(this).css('list-style':'то что нужно')

- не?

и при закрытии

.removeAttr('style');

:)

V
На сайте с 10.01.2012
Offline
85
#8

Добавить class сообразил как


if ($(this).children("ul").is(":hidden")) {
$(this).children("ul").slideDown() ;
$(this).addClass('selected') ;
}

А вот как remove ранее выставленный что-то никак

[Удален]
#9

Varenik, если с класс, то

.removeClass("selected")

V
На сайте с 10.01.2012
Offline
85
#10

Это то понятно

Структура какого вида:

 $('.menu-v').find('li.selected').removeClass('selected');

Должна убрать класс у всех LI .selected, поскольку берем блок menu-v ищем у них все элементы с классом selected и удаляем его, но почему-то не срабатывает

12

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий