【发布时间】:2021-05-29 12:24:21
【问题描述】:
我正在尝试编辑我的 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', '.navigation__tier-1 > .navigation__item--with-children', function (evt) {
$($('.navigation__tier-1 > .navigation__item', $nav)[$(this).index()]).trigger(evt.type);
}).on('touchstart touchend click', '.navigation__tier-1 > .navigation__item--with-children > .navigation__link', 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', '.navigation__tier-1 > .navigation__item--with-children > .navigation__children-toggle', 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');
}
};
谢谢!
【问题讨论】:
标签: javascript html css shopify megamenu