Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhil Hughes <me@iamphill.com>2017-08-01 10:49:03 +0300
committerPhil Hughes <me@iamphill.com>2017-08-01 10:49:03 +0300
commit20bfc4f679bd63f71af716d4910c5c22e33180c0 (patch)
tree77875dc518481f280051ecf9a2703006d4059ab8 /app/assets/javascripts/fly_out_nav.js
parentf20a48494a4d60ddf311b85ce51ba0cb788390be (diff)
added mouseleave timeout with JS
Diffstat (limited to 'app/assets/javascripts/fly_out_nav.js')
-rw-r--r--app/assets/javascripts/fly_out_nav.js90
1 files changed, 72 insertions, 18 deletions
diff --git a/app/assets/javascripts/fly_out_nav.js b/app/assets/javascripts/fly_out_nav.js
index f2151396d43..93101f123b5 100644
--- a/app/assets/javascripts/fly_out_nav.js
+++ b/app/assets/javascripts/fly_out_nav.js
@@ -1,3 +1,16 @@
+let hideTimeoutInterval = 0;
+let hideTimeout;
+let subitems;
+
+export const getHideTimeoutInterval = () => hideTimeoutInterval;
+
+export const hideAllSubItems = () => {
+ subitems.forEach((el) => {
+ el.parentNode.classList.remove('is-over');
+ el.style.display = 'none'; // eslint-disable-line no-param-reassign
+ });
+};
+
export const calculateTop = (boundingRect, outerHeight) => {
const windowHeight = window.innerHeight;
const bottomOverflow = windowHeight - (boundingRect.top + outerHeight);
@@ -6,23 +19,64 @@ export const calculateTop = (boundingRect, outerHeight) => {
boundingRect.top;
};
+export const showSubLevelItems = (el) => {
+ const $subitems = el.querySelector('.sidebar-sub-level-items');
+
+ if (!$subitems) return;
+
+ hideAllSubItems();
+
+ if (el.classList.contains('is-over')) {
+ clearTimeout(hideTimeout);
+ } else {
+ $subitems.style.display = 'block';
+ el.classList.add('is-over');
+ }
+
+ const boundingRect = el.getBoundingClientRect();
+ const top = calculateTop(boundingRect, $subitems.offsetHeight);
+ const isAbove = top < boundingRect.top;
+
+ $subitems.style.transform = `translate3d(0, ${top}px, 0)`;
+
+ if (isAbove) {
+ $subitems.classList.add('is-above');
+ }
+};
+
+export const hideSubLevelItems = (el) => {
+ const $subitems = el.querySelector('.sidebar-sub-level-items');
+ const hideFn = () => {
+ el.classList.remove('is-over');
+ $subitems.style.display = 'none';
+ $subitems.classList.remove('is-above');
+
+ hideTimeoutInterval = 0;
+ };
+
+ if ($subitems && hideTimeoutInterval) {
+ hideTimeout = setTimeout(hideFn, hideTimeoutInterval);
+ } else if ($subitems) {
+ hideFn();
+ }
+};
+
+export const setMouseOutTimeout = (el) => {
+ if (el.closest('.sidebar-sub-level-items')) {
+ hideTimeoutInterval = 250;
+ } else {
+ hideTimeoutInterval = 0;
+ }
+};
+
export default () => {
- $('.sidebar-top-level-items > li:not(.active)').on('mouseover', (e) => {
- const $this = e.currentTarget;
- const $subitems = $('.sidebar-sub-level-items', $this).show();
-
- if ($subitems.length) {
- const boundingRect = $this.getBoundingClientRect();
- const top = calculateTop(boundingRect, $subitems.outerHeight());
- const isAbove = top < boundingRect.top;
-
- $subitems.css({
- transform: `translate3d(0, ${top}px, 0)`,
- });
-
- if (isAbove) {
- $subitems.addClass('is-above');
- }
- }
- }).on('mouseout', e => $('.sidebar-sub-level-items', e.currentTarget).hide().removeClass('is-above'));
+ const items = [...document.querySelectorAll('.sidebar-top-level-items > li:not(.active)')];
+ subitems = [...document.querySelectorAll('.sidebar-top-level-items > li:not(.active) .sidebar-sub-level-items')];
+
+ items.forEach((el) => {
+ el.addEventListener('mouseenter', e => showSubLevelItems(e.currentTarget));
+ el.addEventListener('mouseleave', e => hideSubLevelItems(e.currentTarget));
+ });
+
+ subitems.forEach(el => el.addEventListener('mouseleave', e => setMouseOutTimeout(e.target)));
};