Разворачивающееся меню на jquery

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

Дано: Шапка с меню. Некоторые пункты меню имеют подменю.

Шапка можеn быть двух видов:

  1. Обычная - при размере экрана меньше 800px меню становится вертикальным и при клике на пункты меню, имеющие подменю оно (подменю) разворачивается, а остальные подменю сворачиваются если были открыты на момент клика. При повторном клике по пункту - подменю сворачивается.
  2. Шапка слева - имеет класс-модификатор .header--aside. Меню в такой шапке вертикальное при любом размере экрана. При клике по ссылкам (.menu__link) пунктов меню имеющим подменю оно (подменю) ведет себя так же как и подменю в обычной шапке при размере экрана меньше 800px.

При размере экрана менее 800px у ссылок меню (.menu__link) имеющих подменю удаляется класс .test-class. Также класс .test-class удаляется у ссылок имеющих подменю при любом размере экрана если шапка имеет класс-модификатор .header--aside.

При загрузке страницы:

  1. Если шапка имеет класс-модификатор .header--aside или размер экрана менее 800px, у ссылок (.menu__link) имеющих подменю удаляется класс .test-class и добавляется обработчик, который разворачивает/сворачивает подменю.
  2. Если у элемента списка (.menu__item) есть класс .active, то у дочерней ссылки (.menu__link) удаляется класс .test-class

При событии resize у окна:

  1. Если шапка НЕ ИМЕЕТ класс-модификатор .header--aside и размер экрана менее 800px, у ссылок (.menu__link) имеющих подменю удаляется класс .test-class и добавляется обработчик, который разворачивает/сворачивает подменю.
  2. Если шапка НЕ ИМЕЕТ класс-модификатор .header--aside и размер экрана больше или равен 800px, у ссылок (.menu__link) имеющих подменю добавляется класс .test-class и удаляется обработчик, который разворачивает/сворачивает подменю.

ПРОБЛЕМА:

После ресайза страницы при клике по ссылке (.menu__link) подменю разворачивается и сворачивается несколько раз. При загрузке страницы все работает нормально. Почему подменю себя так ведет? Если кому-то удобнее codepen

    <div class="header header--aside">
      <nav class="header__menu menu">
        <ul class="menu__list">
          <li class="menu__item active">
            <a href="http://yandex.ru" class="menu__link test-class" target="_blank">text 1</a>
            <ul class="menu__dropdown">
              <li class="menu__dropdown-item"><a href="">lorem ipsum</a></li>
              <li class="menu__dropdown-item"><a href="">lorem ipsum</a></li>
              <li class="menu__dropdown-item"><a href="">lorem ipsum</a></li>
            </ul>
          </li>
          <li class="menu__item">
            <a href="http://yandex.ru" class="menu__link test-class" target="_blank">text 2</a>
            <ul class="menu__dropdown">
              <li class="menu__dropdown-item"><a href="">text</a></li>
              <li class="menu__dropdown-item"><a href="">text</a></li>
              <li class="menu__dropdown-item"><a href="">text</a></li>
            </ul>
          </li>
          <li class="menu__item">
            <a href="#" class="menu__link test-class">text 3</a>
            <ul class="menu__dropdown">
              <li class="menu__dropdown-item"><a href="">lorem ipsum</a></li>
              <li class="menu__dropdown-item"><a href="">lorem ipsum</a></li>
              <li class="menu__dropdown-item"><a href="">lorem ipsum</a></li>
            </ul>
          </li>
          <li class="menu__item"><a href="#" class="menu__link test-class">text 4</a></li>
          <li class="menu__item"><a href="#" class="menu__link test-class">text 5</a></li>
        </ul>
      </nav>
    </div>

    <style>
      .menu__list {
        list-style: none;
        margin: 0;
        padding: 0;
      }
      .menu__dropdown {
        display: none;
        list-style: none;
        margin: 0;
        padding: 0 0 0 20px;
      }
      .menu__dropdown-item {
        font-size: 14px;
      }
      .menu__item {
        margin-bottom: 6px;
        font-size: 18px;
      }
      .menu__item.active a {
        color: red;
      }
      .menu .test-class {
        position: relative;
      }
      .menu .test-class::after {
        content: "";
        position: absolute;
        top: 50%;
        right: -20px;
        width: 10px;
        height: 1px;
        background-color: red;
      }
      .menu a {
        color: #000;
        text-decoration: none;
        font-family: Arial, sans-serif;
        text-transform: uppercase;
      }
      
      .header__toggle {
        display: none;
      }
      @media screen and (min-width: 800px) {
        .header:not(.header--aside) .menu__list {
          display: flex;
        }
        .header:not(.header--aside) .menu__item {
          position: relative;
          margin-right: 40px;
        }
        .header:not(.header--aside) .menu__dropdown {
          position: absolute;
          left: 0;
          bottom: 0;
          display: none;
          width: 200px;
          padding: 20px;
          transform: translateY(100%);
          background-color: #f7f7f7;
        }
        .header:not(.header--aside) .menu__dropdown:hover {
          display: block;
        }
        .header:not(.header--aside) .menu__link:hover + .header:not(.header--aside) .menu__dropdown {
          display: block;
        }
      }
    </style>

    <script>
      const menu = $('.menu');
      const menuLinks = $('.menu__link');
      const isAside = $('.header').hasClass('header--aside');
      const breakpoint = 800;
      
      
      changeClass();
      chageHandlerState();
      
      function changeClass() { 
        let width = $(window).width();
        
        menuLinks.each(function() {
          const link = $(this);
          const parent = link.parent();
          const hasNext = link.next().length !== 0;
          
          if ( ((isAside || width < breakpoint) && hasNext) || parent.hasClass('active')) {
            link.removeClass('test-class');
          } else if (!isAside && width >= breakpoint && !parent.hasClass('active')) {
            link.addClass('test-class');
          } 
        }); 
      }
      
      function openMobile(evt) {
        evt.preventDefault();
        const target = $(evt.target).closest('.menu__link');
        const item = $(evt.target).closest('.menu__item');
        
        
        const dropdown = target.next();
        if (dropdown.length !== 0) {
          const siblings = item.siblings();
                   
          siblings.find('.menu__dropdown').slideUp(300);
          dropdown.slideToggle(300);
        }
      }
      
      function chageHandlerState() {
        if ($(window).width() < breakpoint || isAside) {
          menu.on('click', openMobile);
        } else if ($(window).width() >= breakpoint && !isAside) {
          menu.off('click', openMobile);
        }
      }

      $(window).on('resize', function() {
        changeClass();
        chageHandlerState();
      });
    </script>

Ответы (0 шт):