Shopify:编辑大型菜单以在点击时打开/关闭,而不是在悬停时打开/关闭?

问题描述

我正在尝试编辑我的 Shopify 的主题。我想通过单击而不是悬停来打开/关闭大型菜单。我自学了编写 HTML 和 CSS 代码,并且刚刚开始探索 javascript/JQuery。我还在学习。无论如何,我希望这将是一个简单的修复。 ?

通过将 javascript 中的“mouseenter”“mouseleave”更改为“click”,我取得了一些进展。通过这样做,我可以通过单击打开菜单并保持打开状态。伟大的。但是我无法在点击时关闭它并且它被卡在打开状态。我想我可能需要在某处使用 .toggle() 方法,但我什至不知道从哪里开始。帮助!

HTML:

   <div id="main-nav">
    <div class="navigation navigation--main" role="navigation" aria-label="Primary navigation">
      <div class="navigation__tier-1-container">
        <ul class="navigation__tier-1">
         
<li class="navigation__item navigation__item--with-children">
              <a href="#" class="navigation__link" aria-haspopup="true" aria-expanded="false" aria-controls="NavigationTier2-1">browse</a>
      
                <a class="navigation__children-toggle" href="#"></a>
              
<div id="NavigationTier2-1" class="navigation__tier-2-container navigation__child-tier">
                  <ul class="navigation__tier-2 navigation__columns navigation__columns--count-2">
                    
                    <li class="navigation__item navigation__column">
                      <a href="/collections/new-arrivals" class="navigation__link">New Arrivals</a>

CSS:

.navigation {
  position: relative;
  z-index: 2;
  text-align: center;
  font-size: {{ font_size_nav_int }}px;
  line-height: 1.5;
}

.navigation ul,.navigation li {
  margin: 0;
  padding: 0;
}

.navigation li {
  list-style: none;
  vertical-align: top;
}

.navigation--left {
  display: none;
  position: absolute;
  left: 0;
  top: 0;
  height: 100%;
  white-space: Nowrap;
  visibility: hidden;
}

@media (min-width: 768px) {
  .navigation--left {
    display: block;
  }
}

.navigation--left .navigation__tier-1-container {
  position: absolute;
  top: 50%;
  margin-top: calc(-18px - 0.75em);
  left: -18px;
  width: 100%;
}

.navigation__item {
  display: block;
}

.navigation__link {
  display: block;
  padding: 10px 18px;
}

.navigation__link[aria-expanded="true"] {
  color: {{ font_col_link_hover }};
}

.navigation .navigation__item--with-children {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
}

.navigation .navigation__item--with-children > .navigation__link {
  max-width: calc(100% - 60px);
}

.navigation .navigation__item--with-children .navigation__tier-2-container,.navigation .navigation__item--with-children .navigation__tier-3-container {
  width: 100%;
}

.navigation .navigation__children-toggle {
  padding: 10px 20px;
  color: inherit;
}

.navigation .navigation__children-toggle:hover {
  color: inherit;
}

.navigation .navigation__children-toggle .feather {
  display: inline-block;
  vertical-align: middle;
  margin-bottom: 1px;
  width: 18px;
  height: 18px;
  stroke-width: 2;
}

.navigation .navigation__tier-1 > .navigation__item {
  display: inline-block;
}

.navigation .navigation__tier-2-container,.navigation .navigation__tier-3-container {
  display: none;
}

Javascript:

     cc.sections.push({
    name: 'store-availability',section: theme.StoreAvailability
  });
  theme.Navigation = {
    init: function init(options) {
      if (options.nav.length == 0) {
        return;
      }
      
      var $nav = options.nav,navHoverDelay = 250,$navLastOpenDropdown = $(),navOpenTimeoutId = -1; // hover events

      $nav.on('mouseenter mouseleave','.navigation__tier-1 > .navigation__item--with-children',function (evt) {
        var $dropdownContainer = $(this); // delay on hover-out

        if (evt.type == 'mouseenter') {
          clearTimeout(navOpenTimeoutId);
          clearTimeout($dropdownContainer.data('navCloseTimeoutId'));
          var $openSiblings = $dropdownContainer.siblings('.navigation__item--show-children'); // close all menus but last opened

          $openSiblings.not($navLastOpenDropdown).removeClass('navigation__item--show-children');
          $navLastOpenDropdown = $dropdownContainer; // show after a delay,based on first-open or not

          var timeoutDelay = $openSiblings.length == 0 ? 0 : navHoverDelay; // open it

          var newNavOpenTimeoutId = setTimeout(function () {
            $dropdownContainer.addClass('navigation__item--show-children').siblings('.navigation__item--show-children').removeClass('navigation__item--show-children');
          },timeoutDelay);
          navOpenTimeoutId = newNavOpenTimeoutId;
          $dropdownContainer.data('navOpenTimeoutId',newNavOpenTimeoutId);
        } else {
          // cancel opening,close after delay,and clear transforms
          clearTimeout($dropdownContainer.data('navOpenTimeoutId'));
          $dropdownContainer.data('navCloseTimeoutId',setTimeout(function () {
            $dropdownContainer.removeClass('navigation__item--show-children');
          },navHoverDelay));
        } // a11y


        $dropdownContainer.children('[aria-expanded]').attr('aria-expanded',evt.type == 'mouseenter');
      }); // touch events on desktop

      var touchHandler = function touchHandler(evt) {
        if ($(window).width() > 767) {
          if (evt.type == 'touchstart') {
            $(this).data('touchstartedAt',evt.timeStamp);
          } else if (evt.type == 'touchend') {
            // down & up in under a second - presume tap
            if (evt.timeStamp - $(this).data('touchstartedAt') < 1000) {
              $(this).data('touchOpenTriggeredAt',evt.timeStamp);

              if ($(this).parent().hasClass('navigation__item--show-children')) {
                // trigger close
                $(this).parent().trigger('mouseleave');
              } else {
                // trigger close on any open items
                $('.navigation:first .navigation__item--show-children').trigger('mouseleave'); // trigger open

                $(this).parent().trigger('mouseenter');
              } // prevent fake click


              return false;
            }
          } else if (evt.type == 'click') {
            // if touch open was triggered very recently,prevent click event
            if ($(this).data('touchOpenTriggeredAt') && evt.timeStamp - $(this).data('touchOpenTriggeredAt') < 1000) {
              return false;
            }
          }
        }
      };

      $nav.on('touchstart touchend click','.navigation__tier-1 > .navigation__item--with-children > .navigation__link',touchHandler); // hit return on dropdown toggle

      var keydownHandler = function keydownHandler(evt) {
        if (evt.which == 13) {
          var $parent = $(this).parent();
          $parent.trigger($parent.hasClass('navigation__item--show-children') ? 'mouseleave' : 'mouseenter');
          return false;
        }
      };

      $nav.on('keydown','.navigation__tier-1 > .navigation__item--with-children > .navigation__children-toggle',keydownHandler); // proxy for desktop nav interaction events

      if (options.proxyTier1Nav) {
        $(options.proxyTier1Nav).on('mouseenter mouseleave',function (evt) {
          $($('.navigation__tier-1 > .navigation__item',$nav)[$(this).index()]).trigger(evt.type);
        }).on('touchstart touchend click',function (evt) {
          var response = touchHandler.bind($($('.navigation__tier-1 > .navigation__item',$nav)[$(this).parent().index()]).children('.navigation__link')[0])(evt);

          if (response === false) {
            return false;
          }
        }).on('keydown',function (evt) {
          if (evt.which == 13) {
            keydownHandler.bind($($('.navigation__tier-1 > .navigation__item',$nav)[$(this).parent().index()]).children('.navigation__children-toggle')[0])(evt);
            return false;
          }
        });
      } // mobile expansion


      $nav.on('click','.navigation__children-toggle',function () {
        if ($(this).parent().toggleClass('navigation__item--mobile-open').hasClass('navigation__item--mobile-open')) {
          $(this).siblings('.navigation__child-tier').stop().slideDown(300,function () {
            $(this).parent().addClass('navigation__item--mobile-open-finished');
            $(this).removeAttr('style');
          });
        } else {
          $(this).siblings('.navigation__child-tier').stop().slideUp(300,function () {
            $(this).parent().removeClass('navigation__item--mobile-open-finished');
            $(this).removeAttr('style');
          });
        }

        return false;
      });
    },destroy: function destroy($nav,$proxyTier1Nav) {
      $nav.add($proxyTier1Nav).off('click mouseenter mouseleave touchstart touchend keydown');
    }
  };

谢谢!

解决方法

通过以下方式处理点击打开和关闭下拉菜单

    $(this).parent().toggleClass('open');
});

然后听下拉菜单外的点击以关闭它,如下所示:

$('body').on('click',function (e) {
    if (!$('li.navigation__item').is(e.target) 
        && $('li.navigation__item').has(e.target).length === 0 
        && $('.open').has(e.target).length === 0
    ) {
        $('li.navigation__item').removeClass('open');
    }
});