我正在进行移动菜单互动
它应该如何运作:
单击“打开”时,会显示带有两个li项目的ul元素。 单击任一li项时,将显示嵌套的ul,如果其中的任何li项具有子项,则标记中还会包含显示“more”的范围。
当我点击“更多”时,我会看到带有li项目的第三级ul,并使用jquery创建一个后退按钮并附加到第三级菜单。
问题
当我点击第一个父李时,我得到了预期的结果。当我点击另一个父li及其子项然后“返回”时,我看到正在创建多个“后退”元素。
我无法理解为什么。我的逻辑可能存在缺陷,我希望有人可以帮助我发现它。或者建议一种方法来更好地调试它。
提前致谢。如果需要,我可以详细说明
小提琴:https://jsfiddle.net/left23/ktdsxk1d/
var toggle_expand = $('.toggle-expand');
var menu = $('#main-nav');
var expand_menu = $('.expand-sub');
var sub_menu = $('.main-menu--sub');
var first_level_item = $('#main-nav > .main-menu > li');
var second_level_menu = $('#main-nav > .main-menu > li > .main-menu--sub-1');
var second_level_item = $('#main-nav > .main-menu > li > .main-menu > li');
var third_level_menu = $('.main-menu--sub-2');
// Mobile Menu Show/Hide.
toggle_expand.on('click', function(e) {
$(this).toggleClass('toggle-expand--open');
menu.toggleClass('main-nav--open');
if (!$(this).hasClass('toggle-expand--open')) {
reset();
}
});
// top level menu items
first_level_item.on('click', function(e) {
first_level_item.not(this).each(function() {
$(this).removeClass('active');
$(this).children(second_level_menu).removeClass('main-menu--sub-open');
});
$(this).toggleClass('active');
$(this).children('.main-menu--sub').toggleClass('main-menu--sub-open');
expandMenu();
});
// second level menu items
function expandMenu() {
expand_menu.on('click', function(e) {
$(this).addClass('expand-sub--open');
$(this).next(third_level_menu).addClass('main-menu--sub-open');
$(this).closest(first_level_item).addClass('active');
e.stopPropagation();
backButton();
});
}
// back button
function backButton() {
var back_button_html = '<div class="back-button">Back</div>';
// append element to bottom of list
third_level_menu.append(back_button_html);
var back_button = $('.back-button');
back_button.on('click', function(e) {
console.log('back');
$(this).parent(third_level_menu).removeClass('main-menu--sub-open');
$(this).parent(third_level_menu).prev(expand_menu).removeClass('expand-sub--open');
$(this).parents('#main-nav > .main-menu > li').addClass('active');
back_button.remove();
e.stopPropagation();
});
}
// reset to starting state
function reset() {
console.log('reset');
first_level_item.removeClass('active');
sub_menu.removeClass('main-menu--sub-open');
expand_menu.removeClass('expand-sub--open');
$('.back-button').remove();
}
答案 0 :(得分:1)
此问题的主要原因是因为您同时在third_level_menu
下创建了两个按钮并绑定了两个按钮click()
事件。因此,如果我们点击more
按钮并切换到另一个first_level_item
并再次点击more
按钮,那么它会不断创建back
按钮并绑定click
个事件到所有back
按钮,包括那些已经绑定click
事件的按钮。
当我们在first_level_item
之间切换时,会expandMenu()
并遇到与上述相同的问题。
因此,在绑定click()
事件之前,我们可以off()
原始事件,以避免多次触发同一事件。此外,选择要删除的右侧back
按钮。
$('.back-button:visible');
并向右third_level_menu
添加新的back
按钮。
$('.main-menu--sub-2:visible');
var toggle_expand = $('.toggle-expand');
var menu = $('#main-nav');
var expand_menu = $('.expand-sub');
var sub_menu = $('.main-menu--sub');
var first_level_item = $('#main-nav > .main-menu > li');
var second_level_menu = $('#main-nav > .main-menu > li > .main-menu--sub-1');
var second_level_item = $('#main-nav > .main-menu > li > .main-menu > li');
var third_level_menu = $('.main-menu--sub-2');
// Mobile Menu Show/Hide.
toggle_expand.on('click', function(e) {
$(this).toggleClass('toggle-expand--open');
menu.toggleClass('main-nav--open');
if (!$(this).hasClass('toggle-expand--open')) {
reset();
}
});
// top level menu items
first_level_item.on('click', function(e) {
first_level_item.not(this).each(function() {
$(this).removeClass('active');
$(this).children(second_level_menu).removeClass('main-menu--sub-open');
});
$(this).toggleClass('active');
$(this).children('.main-menu--sub').toggleClass('main-menu--sub-open');
expandMenu();
});
// second level menu items
function expandMenu() {
expand_menu.off('click').on('click', function(e) {
$(this).addClass('expand-sub--open');
$(this).next(third_level_menu).addClass('main-menu--sub-open');
$(this).closest(first_level_item).addClass('active');
e.stopPropagation();
backButton();
});
}
// back button
function backButton() {
var back_button_html = '<div class="back-button">Back</div>';
// append element to bottom of list
$('.main-menu--sub-2:visible').append(back_button_html);
var back_button = $('.back-button:visible');
back_button.on('click', function(e) {
console.log('back');
$(this).parent(third_level_menu).removeClass('main-menu--sub-open');
$(this).parent(third_level_menu).prev(expand_menu).removeClass('expand-sub--open');
$(this).parents('#main-nav > .main-menu > li').addClass('active');
$(this).remove();
e.stopPropagation();
});
}
// reset to starting state
function reset() {
console.log('reset');
first_level_item.removeClass('active');
// not sure if we want this! Consider a starting state
sub_menu.removeClass('main-menu--sub-open');
expand_menu.removeClass('expand-sub--open');
$('.back-button').remove();
}
&#13;
.main-nav {
display: none;
width: 90%;
}
.main-nav--open {
display: block;
}
.main-nav {
z-index: 99;
}
.main-nav>ul.main-menu {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-items: flex-start;
padding: 0 1rem;
}
.main-nav>ul.main-menu>li.main-menu__item {
flex: 0 1 33%;
position: relative;
display: flex;
justify-content: space-around;
align-content: flex-start;
background: red;
margin-right: 1rem;
}
.main-nav>ul.main-menu>li.main-menu__item>a {
display: block;
padding: 1rem;
text-align: center;
color: white;
font-weight: 700;
text-transform: uppercase;
text-decoration: none;
transition: padding 0.2s;
}
.main-nav>ul.main-menu>li.main-menu__item.active>a {
padding: 2rem 1rem;
}
.main-nav>ul.main-menu>li.main-menu__item.active>.main-menu--sub-open {
z-index: 20;
}
.main-nav>ul.main-menu>li.main-menu__item>ul.main-menu.main-menu--sub.main-menu--sub-1 {
display: none;
position: fixed;
background: rgba(0, 0, 0, 0.6);
padding: 1rem 1rem 0;
width: 50vw;
top: 160px;
left: 0;
bottom: 0;
}
.main-nav>ul.main-menu>li.main-menu__item>ul.main-menu.main-menu--sub.main-menu--sub-1.main-menu--sub-open {
display: block;
}
.main-nav>ul.main-menu>li.main-menu__item>ul.main-menu.main-menu--sub.main-menu--sub-1>li.main-menu__item.main-menu__item--with-sub.main-menu__item--sub.main-menu__item--sub-1 {
border-top: 1px solid white;
display: flex;
justify-content: space-between;
}
.main-nav>ul.main-menu>li.main-menu__item>ul.main-menu.main-menu--sub.main-menu--sub-1>li.main-menu__item.main-menu__item--with-sub.main-menu__item--sub.main-menu__item--sub-1:first-child {
border: 0 none;
}
.main-nav>ul.main-menu>li.main-menu__item>ul.main-menu.main-menu--sub.main-menu--sub-1>li.main-menu__item.main-menu__item--with-sub.main-menu__item--sub.main-menu__item--sub-1>a {
display: block;
padding: 1rem 0;
color: white;
font-weight: 700;
text-transform: uppercase;
text-decoration: none;
}
.main-nav>ul.main-menu>li.main-menu__item>ul.main-menu.main-menu--sub.main-menu--sub-1>li.main-menu__item.main-menu__item--with-sub.main-menu__item--sub.main-menu__item--sub-1>ul.main-menu.main-menu--sub.main-menu--sub-1.main-menu--sub-2 {
display: none;
position: fixed;
background: rgba(0, 0, 0, 1);
padding: 1rem 1rem 0;
width: 50vw;
top: 160px;
left: 0;
bottom: 0;
z-index: 5;
}
.main-nav>ul.main-menu>li.main-menu__item>ul.main-menu.main-menu--sub.main-menu--sub-1>li.main-menu__item.main-menu__item--with-sub.main-menu__item--sub.main-menu__item--sub-1>ul.main-menu.main-menu--sub.main-menu--sub-1.main-menu--sub-2.main-menu--sub-open {
display: block;
}
.main-nav>ul.main-menu>li.main-menu__item>ul.main-menu.main-menu--sub.main-menu--sub-1>li.main-menu__item.main-menu__item--with-sub.main-menu__item--sub.main-menu__item--sub-1>ul.main-menu.main-menu--sub.main-menu--sub-1.main-menu--sub-2>li.main-menu__item.main-menu__item--with-sub.main-menu__item--sub.main-menu__item--sub-1.main-menu__item--sub-2 {
border-top: 1px solid white;
display: flex;
justify-content: space-between;
}
.main-nav>ul.main-menu>li.main-menu__item>ul.main-menu.main-menu--sub.main-menu--sub-1>li.main-menu__item.main-menu__item--with-sub.main-menu__item--sub.main-menu__item--sub-1>ul.main-menu.main-menu--sub.main-menu--sub-1.main-menu--sub-2>li.main-menu__item.main-menu__item--with-sub.main-menu__item--sub.main-menu__item--sub-1.main-menu__item--sub-2:first-child {
border: 0 none;
}
.main-nav>ul.main-menu>li.main-menu__item>ul.main-menu.main-menu--sub.main-menu--sub-1>li.main-menu__item.main-menu__item--with-sub.main-menu__item--sub.main-menu__item--sub-1>ul.main-menu.main-menu--sub.main-menu--sub-1.main-menu--sub-2>li.main-menu__item.main-menu__item--with-sub.main-menu__item--sub.main-menu__item--sub-1.main-menu__item--sub-2>a {
display: block;
padding: 1rem 0;
color: white;
font-weight: 700;
text-transform: uppercase;
text-decoration: none;
}
.toggle-expand {
display: inline-block;
text-align: right;
padding: 1rem;
text-decoration: none;
}
.toggle-expand--open {
background-color: white;
}
.toggle-expand__open {
display: inline-block;
text-align: center;
}
.toggle-expand--open .toggle-expand__open {
display: none;
}
.toggle-expand__close {
display: none;
text-align: center;
}
.toggle-expand--open .toggle-expand__close {
display: inline-block;
}
.back-button {
cursor: pointer;
display: inline-block;
height: 2rem;
width: auto;
color: white;
position: absolute;
right: 1rem;
padding: 1rem;
background: red;
}
.expand-sub {
cursor: pointer;
display: inline-block;
height: 2rem;
width: auto;
color: black;
position: absolute;
right: 1rem;
padding: 1rem;
background: rgba(255, 255, 255, 0.4);
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<a href="#" id="toggle-expand" class="toggle-expand toggle-expand--open">
<span class="toggle-expand__open">
Close
</span>
<span class="toggle-expand__close">Click to open menu</span>
</a>
<nav id="main-nav" class="main-nav">
<ul class="main-menu">
<li class="main-menu__item main-menu__item--with-sub">
<a class="main-menu__link main-menu__link--with-sub" href="#">
Item 1
</a>
<ul class="main-menu main-menu--sub main-menu--sub-1">
<li class="main-menu__item main-menu__item--with-sub main-menu__item--sub main-menu__item--sub-1 main-menu__item--with-sub">
<a class="main-menu__link main-menu__link--with-sub main-menu__link--sub main-menu__link--sub-1 main-menu__link--with-sub" href="#">
Item 1 Child 1</a>
<span class="expand-sub">more</span>
<ul class="main-menu main-menu--sub main-menu--sub-1 main-menu--sub main-menu--sub-2">
<li class="main-menu__item main-menu__item--with-sub main-menu__item--sub main-menu__item--sub-1 main-menu__item--with-sub main-menu__item--sub main-menu__item--sub-2">
<a class="main-menu__link main-menu__link--with-sub main-menu__link--sub main-menu__link--sub-1 main-menu__link--with-sub main-menu__link--sub main-menu__link--sub-2" href="#">Item 1 Child 1 Grandchild 1</a>
</li>
<li class="main-menu__item main-menu__item--with-sub main-menu__item--sub main-menu__item--sub-1 main-menu__item--with-sub main-menu__item--sub main-menu__item--sub-2">
<a class="main-menu__link main-menu__link--with-sub main-menu__link--sub main-menu__link--sub-1 main-menu__link--with-sub main-menu__link--sub main-menu__link--sub-2" href="#">Item 1 Child 1 Grandchild 2</a>
</li>
</ul>
</li>
</ul>
</li>
<li class="main-menu__item main-menu__item--with-sub">
<a class="main-menu__link main-menu__link--with-sub" href="#">
Item 2
</a>
<ul class="main-menu main-menu--sub main-menu--sub-1">
<li class="main-menu__item main-menu__item--with-sub main-menu__item--sub main-menu__item--sub-1 main-menu__item--with-sub">
<a class="main-menu__link main-menu__link--with-sub main-menu__link--sub main-menu__link--sub-1 main-menu__link--with-sub" href="#">
Item 2 Child 1</a>
<span class="expand-sub">more</span>
<ul class="main-menu main-menu--sub main-menu--sub-1 main-menu--sub main-menu--sub-2">
<li class="main-menu__item main-menu__item--with-sub main-menu__item--sub main-menu__item--sub-1 main-menu__item--with-sub main-menu__item--sub main-menu__item--sub-2">
<a class="main-menu__link main-menu__link--with-sub main-menu__link--sub main-menu__link--sub-1 main-menu__link--with-sub main-menu__link--sub main-menu__link--sub-2" href="#">Item 2 Child 1 Grandchild 1</a>
</li>
<li class="main-menu__item main-menu__item--with-sub main-menu__item--sub main-menu__item--sub-1 main-menu__item--with-sub main-menu__item--sub main-menu__item--sub-2">
<a class="main-menu__link main-menu__link--with-sub main-menu__link--sub main-menu__link--sub-1 main-menu__link--with-sub main-menu__link--sub main-menu__link--sub-2" href="#">Item 2 Child 1 Grandchild 2</a>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</nav>
&#13;