Распространение jQuery и несколько классов
-
13-12-2019 - |
Вопрос
-- ОБНОВЛЯТЬ --
Я был немного глуп, дочерние UL закрывали родительский список (затухание непрозрачности), поэтому я не мог щелкнуть группы после того, как щелкнул их один раз.Упс!В любом случае спасибо, что помогли мне, ребята!
Проблема с распространением jQuery — это то, с чем сталкиваются все.Но вот мой случай, который я не могу найти, чтобы исправить (или, может быть, я туп, чтобы не смотреть в нужные места, или мои навыки jQuery просто недостаточно хороши, чтобы понять).
Базовый вариант — у меня есть несколько групп, и в группах есть несколько вариантов.при нажатии на одну из групп всплывают параметры.НО, когда я нажимаю один из вариантов, все всплывающее окно снова срабатывает, потому что это дочерние элементы родителя, и поэтому он распознает класс, в котором пойманы дети.
Мой HTML выглядит следующим образом:
<div id="buttons">
<ul>
<li class="group">Group 1
<ul>
<li class="link">Link</li>
</ul>
</li>
<li class="group">Group 2
<ul>
<li class="link">Link</li>
</ul>
</li>
<li class="group">Group 3
<ul>
<li class="link">Link</li>
</ul>
</li>
<li class="group">Group 4
<ul>
<li class="link">Link</li>
</ul>
</li>
</ul>
</div>
Думаю, это выглядит довольно просто, и я полагаю, в этом нет ничего плохого.Это просто списки, вложенные в списки.
Но потом мой код jQuery.Это выглядит так:
$(".group").click(function(event) {
// if ($(event.target).is('ul li ul li')) return false;
$(".group").children("ul").animate({top: 0, opacity: 0}, 200);
var liHeight = ($(this).children("ul").children("li").height())+20;
var totalOptions = $(this).children("ul").children("li").length;
var combinedHeight = totalOptions * liHeight;
var slideIn = -(16+combinedHeight) // formula doing math on slidedistance
$(this).children("ul").animate({
top: slideIn,
opacity: 1
}, 600);
/*
$(".link").click(function(event) {
event.stopPropagation();
});
*/
});
Что он на самом деле делает:
- сброс дочерних групп в верхнюю позицию по умолчанию
- получение выбранной группы
- получение высоты общего ребенка ul целевой группы
- подготовка дистанции для анимации
- запуск анимации
С этим проблем нет, и все работает так, как я хочу, но когда я нажимаю на li
внутри ul
s, он просто продолжает запускать анимацию, а это не входит в план.
Как вы могли заметить, я закомментировал 2 блока кода.Это два разных способа управления распространением, которые я нашел, когда наткнулся на Интернет в поисках относительной проблемы с ответом.Однако оба не дают хорошего результата.Происходит то, что распространение фактически прекращается, но при этом становится невозможным щелкать разные группы.
В этом суть проблемы.Я думаю, мне просто нужно добавить одну или две строчки, но я просто не могу придумать, что должно подойти, почти перепробовал все, что пришло мне в голову.
Кроме того, если вы не можете найти ответы, но у вас есть отзывы по разметке кода или чему-то еще, это также приветствуется (я изучаю дизайн взаимодействия/веб-разработку, поэтому я тоже был бы признателен :))
Решение
Не следует устанавливать обработчик кликов на .group
элемент, но только на элементе переключения.
<li class="group">
<a class="toggle">Group 2</a>
<ul>
<!-- contents to show & hide -->
</ul>
</li>
$(".toggle").click(function(e) {
$(this).next()... // to reference the ul
})
Другие советы
Просто переместите следующий код за пределы .group
обработчик кликов:
$(".link").click(function(event) {
event.stopPropagation();
});
Полный код:
$(".group").click(function(event) {
// if ($(event.target).is('ul li ul li')) return false;
$(".group").children("ul").animate({top: 0, opacity: 0}, 200);
var liHeight = ($(this).children("ul").children("li").height())+20;
var totalOptions = $(this).children("ul").children("li").length;
var combinedHeight = totalOptions * liHeight;
var slideIn = -(16+combinedHeight) // formula doing math on slidedistance
$(this).children("ul").animate({
top: slideIn,
opacity: 1
}, 600);
});
$(".link").click(function(event) {
event.stopPropagation();
});
Я бы предложил альтернативный способ click
слушатель.Если вы используете on
метод в jQuery — вы можете делегировать прослушиватель дочернему элементу.Вот так:
$('#buttons').on('click', 'li', function(e){
var li = $(this);
if(li.hasClass('group')){
alert('group was clicked');
}
else if(li.hasClass('link')){
alert('link was clicked');
e.stopPropagation();
}
});
Живой пример этого кода здесь - http://jsfiddle.net/skip405/YWzxB/
Уведомление:если вы удалите stopPropagation
часть на link
делегация - вот увидишь два оповещения.Сначала – для link
а затем – для group
.