问题描述
我正在尝试编辑我的 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');
}
});