UNPKG

baseframe-js

Version:

A suite of useful Javascript plugins and functions to help with Front-end Development on websites

127 lines (126 loc) 4.75 kB
import $ from 'cash-dom'; import { getDataOptions } from "./util/helpers"; import Store from "./core/Store"; const VERSION = "2.0.0"; const DATA_NAME = 'NavDesktop'; const EVENT_NAME = 'navDesktop'; const DEFAULTS = { stopWidth: 768, delay: 800, navLeavingDelay: 800, outerElem: document.body, cssPrefix: 'menu', hoverCss: 'hover' }; export default class NavDesktop { element; params; cssList; stayHover; navLeaving; static defaults = DEFAULTS; static version = VERSION; static pluginName = DATA_NAME; constructor(element, options) { const s = this; s.stayHover; s.navLeaving; s.element = element; const dataOptions = getDataOptions(element, EVENT_NAME); s.params = $.extend({}, NavDesktop.defaults, options, dataOptions); const { cssPrefix } = s.params; s.cssList = { // menuOuterOpen: `${cssPrefix}--outer-open`, menuHasUL: `${cssPrefix}__has-ul`, menuNoUl: `${cssPrefix}__no-ul`, menuElemEdge: `${cssPrefix}__elem-on-edge`, menuHovered: `${cssPrefix}--hover`, menuLeaving: `${cssPrefix}--leaving`, }; s.addCssToElems(); s.handleEvents(); return s; } static remove(element, plugin) { $(element).each(function () { const s = plugin || Store(this, DATA_NAME); const $el = $(s.element); $el.find('ul').off(`mouseover.${EVENT_NAME} focusin.${EVENT_NAME} focusout.${EVENT_NAME}`); $el.off(`mouseout.${EVENT_NAME}`); Store(this, DATA_NAME, null); }); } addCssToElems() { const s = this; const css = s.cssList; $('li', s.element) .addClass(css.menuNoUl) .has('ul').each(function () { $(this).removeClass(css.menuNoUl); if (!$(this).hasClass(css.menuHasUL)) { $(this).addClass(css.menuHasUL); } }); } handleEvents() { const s = this; let prevEvent = null; const evtTracker = (elem, e, cb) => { const currEvent = e.type; const containsOrISElem = elem.isSameNode(e.target) ? true : !!$(e.target).parents(elem).length; if (!prevEvent || (prevEvent !== currEvent && containsOrISElem)) { prevEvent = currEvent; cb(); } }; $(s.element).find('ul').on(`mouseover.${EVENT_NAME} focusin.${EVENT_NAME}`, 'li, ul', function (e) { const li = this; const css = s.cssList; const p = s.params; evtTracker(li, e, () => { s.edgeDetector(li); const $liLiParents = $(li).parents('li'); li.classList.add(p.hoverCss); $liLiParents.addClass(p.hoverCss); $(li).find(`.${p.hoverCss}`).removeClass(p.hoverCss); $(li).siblings('li').removeClass(p.hoverCss); $liLiParents.length === 0 && $(s.element).find(`.${p.hoverCss}`).removeClass(p.hoverCss); s.navLeaving && clearTimeout(s.navLeaving); s.stayHover && clearTimeout(s.stayHover); $(p.outerElem).addClass(css.menuHovered).removeClass(css.menuLeaving); }); }).on(`mouseout.${EVENT_NAME} focusout.${EVENT_NAME}`, 'li, ul', function (e) { const liOrUl = this; const p = s.params; const css = s.cssList; evtTracker(liOrUl, e, () => { s.stayHover = setTimeout(() => { $(s.element).find(`.${p.hoverCss}`).removeClass(`${p.hoverCss} ${css.menuElemEdge}`); $(s.element).find(`.${css.menuElemEdge}`).removeClass(css.menuElemEdge); $(p.outerElem) .removeClass(css.menuHovered) .addClass(css.menuLeaving); s.navLeaving = setTimeout(() => { $(p.outerElem).removeClass(css.menuLeaving); }, p.navLeavingDelay); }, p.delay); }); }); } edgeDetector(liOrUl) { const s = this; const { stopWidth } = s.params; const css = s.cssList; const dw = $(window).width(); if (stopWidth < dw) { const $uls = $(liOrUl).find('ul'); if ($uls.length) { const ul = $uls[0], l = $(ul).offset().left, uw = ul.scrollWidth, fullyVisible = (l + uw <= dw); if (!fullyVisible) { liOrUl.classList.add(css.menuElemEdge); } } } } }