带有后退按钮的jquery多级菜单 - 正在创建多个后退按钮元素

时间:2018-04-25 14:34:25

标签: jquery

我正在进行移动菜单互动

它应该如何运作:

单击“打开”时,会显示带有两个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();
}

1 个答案:

答案 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');

&#13;
&#13;
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;
&#13;
&#13;