Issue #3191716 by mherchel, Abhijith S, lauriii, andrewmacpherson, katannshaw: Opening desktop dropdown menu using pointer device requires two taps/clicks

merge-requests/1068/head
Lauri Eskola 2021-03-05 17:46:50 +02:00
parent 468d666032
commit 5a389e3b06
No known key found for this signature in database
GPG Key ID: 382FC0F5B0DF53F8
4 changed files with 82 additions and 25 deletions

View File

@ -22,6 +22,7 @@
});
if (visibility === true) {
Drupal.olivero.closeAllSubNav();
searchWideWrapper.classList.add('is-active');
} else {
searchWideWrapper.classList.remove('is-active');

View File

@ -30,6 +30,7 @@
});
if (visibility === true) {
Drupal.olivero.closeAllSubNav();
searchWideWrapper.classList.add('is-active');
} else {
searchWideWrapper.classList.remove('is-active');

View File

@ -38,6 +38,7 @@
.classList.add('is-active');
} else {
button.setAttribute('aria-expanded', 'false');
topLevelMenuITem.classList.remove('is-touch-event');
topLevelMenuITem
.querySelector('.primary-nav__menu--level-2')
.classList.remove('is-active');
@ -46,8 +47,7 @@
Drupal.olivero.toggleSubNav = toggleSubNav;
// Add hover and click event listeners onto each sub navigation parent and its
// button.
// Add event listeners onto each sub navigation parent and button.
secondLevelNavMenus.forEach((el) => {
const button = el.querySelector(
'.primary-nav__button-toggle, .primary-nav__menu-link--button',
@ -56,20 +56,39 @@
button.removeAttribute('aria-hidden');
button.removeAttribute('tabindex');
button.addEventListener('click', (e) => {
const topLevelMenuITem = e.currentTarget.parentNode;
toggleSubNav(topLevelMenuITem);
});
// If touch event, prevent mouseover event from triggering the submenu.
el.addEventListener(
'touchstart',
() => {
el.classList.add('is-touch-event');
},
{ passive: true },
);
el.addEventListener('mouseover', (e) => {
if (isDesktopNav()) {
toggleSubNav(e.currentTarget, true);
el.addEventListener('mouseover', () => {
if (isDesktopNav() && !el.classList.contains('is-touch-event')) {
el.classList.add('is-active-mouseover-event');
toggleSubNav(el, true);
// Timeout is added to ensure that users of assistive devices (such as
// mouse grid tools) do not simultaneously trigger both the mouseover
// and click events. When these events are triggered together, the
// submenu to appear to not open.
setTimeout(() => {
el.classList.remove('is-active-mouseover-event');
}, 500);
}
});
el.addEventListener('mouseout', (e) => {
button.addEventListener('click', () => {
if (!el.classList.contains('is-active-mouseover-event')) {
toggleSubNav(el);
}
});
el.addEventListener('mouseout', () => {
if (isDesktopNav()) {
toggleSubNav(e.currentTarget, false);
toggleSubNav(el, false);
}
});
});
@ -93,7 +112,9 @@
let subNavsAreOpen = false;
secondLevelNavMenus.forEach((el) => {
const button = el.querySelector('.primary-nav__button-toggle');
const button = el.querySelector(
'.primary-nav__button-toggle, .primary-nav__menu-link--button',
);
const state = button.getAttribute('aria-expanded') === 'true';
if (state) {
@ -108,8 +129,24 @@
// Ensure that desktop submenus close when ESC key is pressed.
document.addEventListener('keyup', (e) => {
if (e.keyCode === 27 && isDesktopNav()) {
closeAllSubNav();
if (e.key === 'Escape' || e.key === 'Esc') {
if (isDesktopNav()) closeAllSubNav();
}
});
// If user taps outside of menu, close all menus.
document.addEventListener(
'touchstart',
(e) => {
if (
areAnySubNavsOpen() &&
!e.target.matches(
'.primary-nav__menu-item--has-children, .primary-nav__menu-item--has-children *',
)
) {
closeAllSubNav();
}
},
{ passive: true },
);
})(Drupal);

View File

@ -26,6 +26,7 @@
topLevelMenuITem.querySelector('.primary-nav__menu--level-2').classList.add('is-active');
} else {
button.setAttribute('aria-expanded', 'false');
topLevelMenuITem.classList.remove('is-touch-event');
topLevelMenuITem.querySelector('.primary-nav__menu--level-2').classList.remove('is-active');
}
}
@ -35,18 +36,28 @@
var button = el.querySelector('.primary-nav__button-toggle, .primary-nav__menu-link--button');
button.removeAttribute('aria-hidden');
button.removeAttribute('tabindex');
button.addEventListener('click', function (e) {
var topLevelMenuITem = e.currentTarget.parentNode;
toggleSubNav(topLevelMenuITem);
el.addEventListener('touchstart', function () {
el.classList.add('is-touch-event');
}, {
passive: true
});
el.addEventListener('mouseover', function (e) {
if (isDesktopNav()) {
toggleSubNav(e.currentTarget, true);
el.addEventListener('mouseover', function () {
if (isDesktopNav() && !el.classList.contains('is-touch-event')) {
el.classList.add('is-active-mouseover-event');
toggleSubNav(el, true);
setTimeout(function () {
el.classList.remove('is-active-mouseover-event');
}, 500);
}
});
el.addEventListener('mouseout', function (e) {
button.addEventListener('click', function () {
if (!el.classList.contains('is-active-mouseover-event')) {
toggleSubNav(el);
}
});
el.addEventListener('mouseout', function () {
if (isDesktopNav()) {
toggleSubNav(e.currentTarget, false);
toggleSubNav(el, false);
}
});
});
@ -62,7 +73,7 @@
function areAnySubNavsOpen() {
var subNavsAreOpen = false;
secondLevelNavMenus.forEach(function (el) {
var button = el.querySelector('.primary-nav__button-toggle');
var button = el.querySelector('.primary-nav__button-toggle, .primary-nav__menu-link--button');
var state = button.getAttribute('aria-expanded') === 'true';
if (state) {
@ -74,8 +85,15 @@
Drupal.olivero.areAnySubNavsOpen = areAnySubNavsOpen;
document.addEventListener('keyup', function (e) {
if (e.keyCode === 27 && isDesktopNav()) {
closeAllSubNav();
if (e.key === 'Escape' || e.key === 'Esc') {
if (isDesktopNav()) closeAllSubNav();
}
});
document.addEventListener('touchstart', function (e) {
if (areAnySubNavsOpen() && !e.target.matches('.primary-nav__menu-item--has-children, .primary-nav__menu-item--has-children *')) {
closeAllSubNav();
}
}, {
passive: true
});
})(Drupal);