UNPKG

framework7

Version:

Full featured mobile HTML framework for building iOS & Android apps

712 lines (704 loc) 28.1 kB
import $ from '../../shared/dom7.js'; import { bindMethods } from '../../shared/utils.js'; import { getSupport } from '../../shared/get-support.js'; const Navbar = { size(el) { const app = this; let $el = $(el); if ($el.hasClass('navbars')) { $el = $el.children('.navbar').each(navbarEl => { app.navbar.size(navbarEl); }); return; } const $innerEl = $el.children('.navbar-inner'); if (!$innerEl.length) return; const needCenterTitle = $innerEl.hasClass('navbar-inner-centered-title') || app.params.navbar[`${app.theme}CenterTitle`]; const needLeftTitle = app.theme === 'ios' && !app.params.navbar[`${app.theme}CenterTitle`]; if (!needCenterTitle && !needLeftTitle) return; if ($el.parents('.tab:not(.tab-active)').length > 0 || $el.parents('.popup:not(.modal-in)').length > 0) { return; } if (app.theme !== 'ios' && app.params.navbar[`${app.theme}CenterTitle`]) { $innerEl.addClass('navbar-inner-centered-title'); } if (app.theme === 'ios' && !app.params.navbar.iosCenterTitle) { $innerEl.addClass('navbar-inner-left-title'); } const $viewEl = $el.parents('.view').eq(0); const left = app.rtl ? $innerEl.children('.right') : $innerEl.children('.left'); const right = app.rtl ? $innerEl.children('.left') : $innerEl.children('.right'); const title = $innerEl.children('.title'); const subnavbar = $innerEl.children('.subnavbar'); const noLeft = left.length === 0; const noRight = right.length === 0; const leftWidth = noLeft ? 0 : left.outerWidth(true); const rightWidth = noRight ? 0 : right.outerWidth(true); const titleWidth = title.outerWidth(true); const navbarStyles = $innerEl.styles(); const navbarWidth = $innerEl[0].offsetWidth; const navbarInnerWidth = navbarWidth - parseInt(navbarStyles.paddingLeft, 10) - parseInt(navbarStyles.paddingRight, 10); const isPrevious = $el.hasClass('navbar-previous'); const sliding = $innerEl.hasClass('sliding'); let router; let dynamicNavbar; if ($viewEl.length > 0 && $viewEl[0].f7View) { router = $viewEl[0].f7View.router; dynamicNavbar = router && router.dynamicNavbar; } let currLeft; let diff; if (noRight) { currLeft = navbarInnerWidth - titleWidth; } if (noLeft) { currLeft = 0; } if (!noLeft && !noRight) { currLeft = (navbarInnerWidth - rightWidth - titleWidth + leftWidth) / 2; } let requiredLeft = (navbarInnerWidth - titleWidth) / 2; if (navbarInnerWidth - leftWidth - rightWidth > titleWidth) { if (requiredLeft < leftWidth) { requiredLeft = leftWidth; } if (requiredLeft + titleWidth > navbarInnerWidth - rightWidth) { requiredLeft = navbarInnerWidth - rightWidth - titleWidth; } diff = requiredLeft - currLeft; } else { diff = 0; } // RTL inverter const inverter = app.rtl ? -1 : 1; if (dynamicNavbar && app.theme === 'ios') { if (title.hasClass('sliding') || title.length > 0 && sliding) { let titleLeftOffset = -(currLeft + diff) * inverter; const titleRightOffset = (navbarInnerWidth - currLeft - diff - titleWidth) * inverter; if (isPrevious) { if (router && router.params.iosAnimateNavbarBackIcon) { const activeNavbarBackLink = $el.parent().find('.navbar-current').children('.left.sliding').find('.back .icon ~ span'); if (activeNavbarBackLink.length > 0) { titleLeftOffset += activeNavbarBackLink[0].offsetLeft; } } } title[0].f7NavbarLeftOffset = titleLeftOffset; title[0].f7NavbarRightOffset = titleRightOffset; } if (!noLeft && (left.hasClass('sliding') || sliding)) { if (app.rtl) { left[0].f7NavbarLeftOffset = -(navbarInnerWidth - left[0].offsetWidth) / 2 * inverter; left[0].f7NavbarRightOffset = leftWidth * inverter; } else { left[0].f7NavbarLeftOffset = -leftWidth; left[0].f7NavbarRightOffset = (navbarInnerWidth - left[0].offsetWidth) / 2; if (router && router.params.iosAnimateNavbarBackIcon && left.find('.back .icon').length > 0) { if (left.find('.back .icon ~ span').length) { const leftOffset = left[0].f7NavbarLeftOffset; const rightOffset = left[0].f7NavbarRightOffset; left[0].f7NavbarLeftOffset = 0; left[0].f7NavbarRightOffset = 0; left.find('.back .icon ~ span')[0].f7NavbarLeftOffset = leftOffset; left.find('.back .icon ~ span')[0].f7NavbarRightOffset = rightOffset - left.find('.back .icon')[0].offsetWidth; } } } } if (!noRight && (right.hasClass('sliding') || sliding)) { if (app.rtl) { right[0].f7NavbarLeftOffset = -rightWidth * inverter; right[0].f7NavbarRightOffset = (navbarInnerWidth - right[0].offsetWidth) / 2 * inverter; } else { right[0].f7NavbarLeftOffset = -(navbarInnerWidth - right[0].offsetWidth) / 2; right[0].f7NavbarRightOffset = rightWidth; } } if (subnavbar.length && (subnavbar.hasClass('sliding') || sliding)) { subnavbar[0].f7NavbarLeftOffset = app.rtl ? subnavbar[0].offsetWidth : -subnavbar[0].offsetWidth; subnavbar[0].f7NavbarRightOffset = -subnavbar[0].f7NavbarLeftOffset; } } // Center title if (needCenterTitle) { let titleLeft = diff; if (app.rtl && noLeft && noRight && title.length > 0) titleLeft = -titleLeft; title.css({ left: `${titleLeft}px` }); } }, hide(el, animate, hideStatusbar, hideOnlyCurrent) { if (animate === void 0) { animate = true; } if (hideStatusbar === void 0) { hideStatusbar = false; } if (hideOnlyCurrent === void 0) { hideOnlyCurrent = false; } const app = this; let $el = $(el); const isDynamic = $el.hasClass('navbar') && $el.parent('.navbars').length && !hideOnlyCurrent; if (isDynamic) $el = $el.parents('.navbars'); if (!$el.length) return; if ($el.hasClass('navbar-hidden')) return; let className = `navbar-hidden${animate ? ' navbar-transitioning' : ''}`; const currentIsLarge = isDynamic ? $el.find('.navbar-current .title-large').length : $el.find('.title-large').length; if (currentIsLarge) { className += ' navbar-large-hidden'; } if (hideStatusbar) { className += ' navbar-hidden-statusbar'; } $el.transitionEnd(() => { $el.removeClass('navbar-transitioning'); }); $el.addClass(className); if (isDynamic) { $el.children('.navbar').each(subEl => { $(subEl).trigger('navbar:hide'); app.emit('navbarHide', subEl); }); } else { $el.trigger('navbar:hide'); app.emit('navbarHide', $el[0]); } }, show(el, animate, hideOnlyCurrent) { if (el === void 0) { el = '.navbar-hidden'; } if (animate === void 0) { animate = true; } if (hideOnlyCurrent === void 0) { hideOnlyCurrent = false; } const app = this; let $el = $(el); const isDynamic = $el.hasClass('navbar') && $el.parent('.navbars').length && !hideOnlyCurrent; if (isDynamic) $el = $el.parents('.navbars'); if (!$el.length) return; if (!$el.hasClass('navbar-hidden')) return; if (animate) { $el.addClass('navbar-transitioning'); $el.transitionEnd(() => { $el.removeClass('navbar-transitioning'); }); } $el.removeClass('navbar-hidden navbar-large-hidden navbar-hidden-statusbar'); if (isDynamic) { $el.children('.navbar').each(subEl => { $(subEl).trigger('navbar:show'); app.emit('navbarShow', subEl); }); } else { $el.trigger('navbar:show'); app.emit('navbarShow', $el[0]); } }, getElByPage(page) { let $pageEl; let $navbarEl; let pageData; if (page.$navbarEl || page.$el) { pageData = page; $pageEl = page.$el; } else { $pageEl = $(page); if ($pageEl.length > 0) pageData = $pageEl[0].f7Page; } if (pageData && pageData.$navbarEl && pageData.$navbarEl.length > 0) { $navbarEl = pageData.$navbarEl; } else if ($pageEl) { $navbarEl = $pageEl.children('.navbar'); } if (!$navbarEl || $navbarEl && $navbarEl.length === 0) return undefined; return $navbarEl[0]; }, getPageByEl(navbarEl) { const $navbarEl = $(navbarEl); if ($navbarEl.parents('.page').length) { return $navbarEl.parents('.page')[0]; } let pageEl; $navbarEl.parents('.view').find('.page').each(el => { if (el && el.f7Page && el.f7Page.navbarEl && $navbarEl[0] === el.f7Page.navbarEl) { pageEl = el; } }); return pageEl; }, collapseLargeTitle(navbarEl) { const app = this; let $navbarEl = $(navbarEl); if ($navbarEl.hasClass('navbars')) { $navbarEl = $navbarEl.find('.navbar'); if ($navbarEl.length > 1) { $navbarEl = $(navbarEl).find('.navbar-large.navbar-current'); } if ($navbarEl.length > 1 || !$navbarEl.length) { return; } } const $pageEl = $(app.navbar.getPageByEl($navbarEl)); $navbarEl.addClass('navbar-large-collapsed'); $pageEl.eq(0).addClass('page-with-navbar-large-collapsed').trigger('page:navbarlargecollapsed'); app.emit('pageNavbarLargeCollapsed', $pageEl[0]); $navbarEl.trigger('navbar:collapse'); app.emit('navbarCollapse', $navbarEl[0]); }, expandLargeTitle(navbarEl) { const app = this; let $navbarEl = $(navbarEl); if ($navbarEl.hasClass('navbars')) { $navbarEl = $navbarEl.find('.navbar-large'); if ($navbarEl.length > 1) { $navbarEl = $(navbarEl).find('.navbar-large.navbar-current'); } if ($navbarEl.length > 1 || !$navbarEl.length) { return; } } const $pageEl = $(app.navbar.getPageByEl($navbarEl)); $navbarEl.removeClass('navbar-large-collapsed'); $pageEl.eq(0).removeClass('page-with-navbar-large-collapsed').trigger('page:navbarlargeexpanded'); app.emit('pageNavbarLargeExpanded', $pageEl[0]); $navbarEl.trigger('navbar:expand'); app.emit('navbarExpand', $navbarEl[0]); }, toggleLargeTitle(navbarEl) { const app = this; let $navbarEl = $(navbarEl); if ($navbarEl.hasClass('navbars')) { $navbarEl = $navbarEl.find('.navbar-large'); if ($navbarEl.length > 1) { $navbarEl = $(navbarEl).find('.navbar-large.navbar-current'); } if ($navbarEl.length > 1 || !$navbarEl.length) { return; } } if ($navbarEl.hasClass('navbar-large-collapsed')) { app.navbar.expandLargeTitle($navbarEl); } else { app.navbar.collapseLargeTitle($navbarEl); } }, initNavbarOnScroll(pageEl, navbarEl, needHide, needCollapse, needTransparent) { const app = this; const support = getSupport(); const $pageEl = $(pageEl); const $navbarEl = $(navbarEl); const $titleLargeEl = $navbarEl.find('.title-large'); const isLarge = $titleLargeEl.length || $navbarEl.hasClass('.navbar-large'); let navbarHideHeight = 44; const snapPageScrollToLargeTitle = app.params.navbar.snapPageScrollToLargeTitle; const snapPageScrollToTransparentNavbar = app.params.navbar.snapPageScrollToTransparentNavbar; let previousScrollTop; let currentScrollTop; let scrollHeight; let offsetHeight; let reachEnd; let action; let navbarHidden; let navbarCollapsed; let navbarTitleLargeHeight; let navbarOffsetHeight; if (needCollapse || needHide && isLarge) { navbarTitleLargeHeight = $navbarEl.css('--f7-navbar-large-title-height'); if (navbarTitleLargeHeight && navbarTitleLargeHeight.indexOf('px') >= 0) { navbarTitleLargeHeight = parseInt(navbarTitleLargeHeight, 10); if (Number.isNaN(navbarTitleLargeHeight) && $titleLargeEl.length) { navbarTitleLargeHeight = $titleLargeEl[0].offsetHeight; } else if (Number.isNaN(navbarTitleLargeHeight)) { if (app.theme === 'ios') navbarTitleLargeHeight = 52;else if (app.theme === 'md') navbarTitleLargeHeight = 88; } } else if ($titleLargeEl.length) { navbarTitleLargeHeight = $titleLargeEl[0].offsetHeight; } else { // eslint-disable-next-line if (app.theme === 'ios') navbarTitleLargeHeight = 52;else if (app.theme === 'md') navbarTitleLargeHeight = 88; } } if (needHide && isLarge) { navbarHideHeight += navbarTitleLargeHeight; } let scrollChanged; let scrollContent; let scrollTimeoutId; let touchEndTimeoutId; const touchSnapTimeout = 70; const desktopSnapTimeout = 300; function calcScrollableDistance() { $pageEl.find('.page-content').each(pageContentEl => { pageContentEl.f7ScrollableDistance = pageContentEl.scrollHeight - pageContentEl.offsetHeight; }); } function snapLargeNavbar() { const inSearchbarExpanded = $navbarEl.hasClass('with-searchbar-expandable-enabled'); if (inSearchbarExpanded) return; if (!scrollContent || currentScrollTop < 0) return; if (currentScrollTop >= navbarTitleLargeHeight / 2 && currentScrollTop < navbarTitleLargeHeight) { $(scrollContent).scrollTop(navbarTitleLargeHeight, 100); } else if (currentScrollTop < navbarTitleLargeHeight) { $(scrollContent).scrollTop(0, 200); } } function snapTransparentNavbar() { const inSearchbarExpanded = $navbarEl.hasClass('with-searchbar-expandable-enabled'); if (inSearchbarExpanded) return; if (!scrollContent || currentScrollTop < 0) return; if (currentScrollTop >= navbarOffsetHeight / 2 && currentScrollTop < navbarOffsetHeight) { $(scrollContent).scrollTop(navbarOffsetHeight, 100); } else if (currentScrollTop < navbarOffsetHeight) { $(scrollContent).scrollTop(0, 200); } } function handleNavbarTransparent() { const isHidden = $navbarEl.hasClass('navbar-hidden') || $navbarEl.parent('.navbars').hasClass('navbar-hidden'); const inSearchbarExpanded = $navbarEl.hasClass('with-searchbar-expandable-enabled'); if (inSearchbarExpanded || isHidden) return; if (!navbarOffsetHeight) { navbarOffsetHeight = navbarEl.offsetHeight; } let opacity = currentScrollTop / navbarOffsetHeight; const notTransparent = $navbarEl.hasClass('navbar-transparent-visible'); opacity = Math.max(Math.min(opacity, 1), 0); if (notTransparent && opacity === 1 || !notTransparent && opacity === 0) { $navbarEl.find('.navbar-bg, .title').css('opacity', ''); return; } if (notTransparent && opacity === 0) { $navbarEl.trigger('navbar:transparenthide'); app.emit('navbarTransparentHide', $navbarEl[0]); $navbarEl.removeClass('navbar-transparent-visible'); $navbarEl.find('.navbar-bg, .title').css('opacity', ''); return; } if (!notTransparent && opacity === 1) { $navbarEl.trigger('navbar:transparentshow'); app.emit('navbarTransparentShow', $navbarEl[0]); $navbarEl.addClass('navbar-transparent-visible'); $navbarEl.find('.navbar-bg, .title').css('opacity', ''); return; } $navbarEl.find('.navbar-bg, .title').css('opacity', opacity); if (snapPageScrollToTransparentNavbar) { if (!support.touch) { clearTimeout(scrollTimeoutId); scrollTimeoutId = setTimeout(() => { snapTransparentNavbar(); }, desktopSnapTimeout); } else if (touchEndTimeoutId) { clearTimeout(touchEndTimeoutId); touchEndTimeoutId = null; touchEndTimeoutId = setTimeout(() => { snapTransparentNavbar(); clearTimeout(touchEndTimeoutId); touchEndTimeoutId = null; }, touchSnapTimeout); } } } let previousCollapseProgress = null; let collapseProgress = null; function handleLargeNavbarCollapse(pageContentEl) { const isHidden = $navbarEl.hasClass('navbar-hidden') || $navbarEl.parent('.navbars').hasClass('navbar-hidden'); if (isHidden) return; const isLargeTransparent = $navbarEl.hasClass('navbar-large-transparent') || $navbarEl.hasClass('navbar-large') && $navbarEl.hasClass('navbar-transparent'); previousCollapseProgress = collapseProgress; const scrollableDistance = Math.min(navbarTitleLargeHeight, pageContentEl.f7ScrollableDistance || navbarTitleLargeHeight); collapseProgress = Math.min(Math.max(currentScrollTop / scrollableDistance, 0), 1); const previousCollapseWasInMiddle = previousCollapseProgress > 0 && previousCollapseProgress < 1; const inSearchbarExpanded = $navbarEl.hasClass('with-searchbar-expandable-enabled'); if (inSearchbarExpanded) return; navbarCollapsed = $navbarEl.hasClass('navbar-large-collapsed'); const $bgEl = $navbarEl.find('.navbar-bg'); if (collapseProgress === 0 && navbarCollapsed) { app.navbar.expandLargeTitle($navbarEl[0]); } else if (collapseProgress === 1 && !navbarCollapsed) { app.navbar.collapseLargeTitle($navbarEl[0]); } if (collapseProgress === 0 && navbarCollapsed || collapseProgress === 0 && previousCollapseWasInMiddle || collapseProgress === 1 && !navbarCollapsed || collapseProgress === 1 && previousCollapseWasInMiddle) { if (app.theme === 'md') { $navbarEl.find('.navbar-inner').css('overflow', ''); } $navbarEl.find('.title').css('opacity', ''); $navbarEl.find('.title-large-text, .subnavbar').css('transform', ''); $navbarEl.find('.title-large-text').css('opacity', ''); if (isLargeTransparent) { $bgEl.css('opacity', ''); } $bgEl.css('transform', ''); } else if (collapseProgress > 0 && collapseProgress < 1) { if (app.theme === 'md') { $navbarEl.find('.navbar-inner').css('overflow', 'visible'); } $navbarEl.find('.title').css('opacity', -0.5 + collapseProgress * 1.5); $navbarEl.find('.title-large-text, .subnavbar').css('transform', `translate3d(0px, ${-1 * collapseProgress * navbarTitleLargeHeight}px, 0)`); $navbarEl.find('.title-large-text').css('opacity', 1 - collapseProgress * 2); if (isLargeTransparent) { $bgEl.css('opacity', collapseProgress); } $bgEl.css('transform', `translate3d(0px, ${-1 * collapseProgress * navbarTitleLargeHeight}px, 0)`); } if (snapPageScrollToLargeTitle) { if (!support.touch) { clearTimeout(scrollTimeoutId); scrollTimeoutId = setTimeout(() => { snapLargeNavbar(); }, desktopSnapTimeout); } else if (touchEndTimeoutId) { clearTimeout(touchEndTimeoutId); touchEndTimeoutId = null; touchEndTimeoutId = setTimeout(() => { snapLargeNavbar(); clearTimeout(touchEndTimeoutId); touchEndTimeoutId = null; }, touchSnapTimeout); } } } function handleTitleHideShow() { if ($pageEl.hasClass('page-with-card-opened')) return; scrollHeight = scrollContent.scrollHeight; offsetHeight = scrollContent.offsetHeight; reachEnd = currentScrollTop + offsetHeight >= scrollHeight; navbarHidden = $navbarEl.hasClass('navbar-hidden') || $navbarEl.parent('.navbars').hasClass('navbar-hidden'); if (reachEnd) { if (app.params.navbar.showOnPageScrollEnd) { action = 'show'; } } else if (previousScrollTop > currentScrollTop) { if (app.params.navbar.showOnPageScrollTop || currentScrollTop <= navbarHideHeight) { action = 'show'; } else { action = 'hide'; } } else if (currentScrollTop > navbarHideHeight) { action = 'hide'; } else { action = 'show'; } if (action === 'show' && navbarHidden) { app.navbar.show($navbarEl, true, true); navbarHidden = false; } else if (action === 'hide' && !navbarHidden) { app.navbar.hide($navbarEl, true, false, true); navbarHidden = true; } previousScrollTop = currentScrollTop; } function handleScroll(e) { scrollContent = this; if (e && e.target && e.target !== scrollContent) { return; } currentScrollTop = scrollContent.scrollTop; scrollChanged = currentScrollTop; if (needCollapse) { handleLargeNavbarCollapse(scrollContent); } else if (needTransparent) { handleNavbarTransparent(); } if ($pageEl.hasClass('page-previous')) return; if (needHide) { handleTitleHideShow(); } } function handeTouchStart() { scrollChanged = false; } function handleTouchEnd() { clearTimeout(touchEndTimeoutId); touchEndTimeoutId = null; touchEndTimeoutId = setTimeout(() => { if (scrollChanged !== false) { if (needTransparent && !needCollapse) { snapTransparentNavbar(); } else { snapLargeNavbar(); } clearTimeout(touchEndTimeoutId); touchEndTimeoutId = null; } }, touchSnapTimeout); } $pageEl.on('scroll', '.page-content', handleScroll, true); if (support.touch && (needCollapse && snapPageScrollToLargeTitle || needTransparent && snapPageScrollToTransparentNavbar)) { app.on('touchstart:passive', handeTouchStart); app.on('touchend:passive', handleTouchEnd); } calcScrollableDistance(); if (needCollapse || needTransparent) { $pageEl.find('.page-content').each(pageContentEl => { if (pageContentEl.scrollTop > 0) handleScroll.call(pageContentEl); }); } app.on('resize', calcScrollableDistance); $pageEl[0].f7DetachNavbarScrollHandlers = function f7DetachNavbarScrollHandlers() { app.off('resize', calcScrollableDistance); delete $pageEl[0].f7DetachNavbarScrollHandlers; $pageEl.off('scroll', '.page-content', handleScroll, true); if (support.touch && (needCollapse && snapPageScrollToLargeTitle || needTransparent && snapPageScrollToTransparentNavbar)) { app.off('touchstart:passive', handeTouchStart); app.off('touchend:passive', handleTouchEnd); } }; } }; export default { name: 'navbar', create() { const app = this; bindMethods(app, { navbar: Navbar }); }, params: { navbar: { scrollTopOnTitleClick: true, iosCenterTitle: true, mdCenterTitle: false, hideOnPageScroll: false, showOnPageScrollEnd: true, showOnPageScrollTop: true, collapseLargeTitleOnScroll: true, snapPageScrollToLargeTitle: true, snapPageScrollToTransparentNavbar: true } }, on: { 'panelBreakpoint panelCollapsedBreakpoint panelResize viewResize resize viewMasterDetailBreakpoint': function onPanelResize() { const app = this; $('.navbar').each(navbarEl => { app.navbar.size(navbarEl); }); }, pageBeforeRemove(page) { if (page.$el[0].f7DetachNavbarScrollHandlers) { page.$el[0].f7DetachNavbarScrollHandlers(); } }, pageBeforeIn(page) { const app = this; if (app.theme !== 'ios') return; let $navbarsEl; const view = page.$el.parents('.view')[0].f7View; const navbarEl = app.navbar.getElByPage(page); if (!navbarEl) { $navbarsEl = page.$el.parents('.view').children('.navbars'); } else { $navbarsEl = $(navbarEl).parents('.navbars'); } if (page.$el.hasClass('no-navbar') || view.router.dynamicNavbar && !navbarEl) { const animate = !!(page.pageFrom && page.router.history.length > 0); app.navbar.hide($navbarsEl, animate); } else { app.navbar.show($navbarsEl); } }, pageReinit(page) { const app = this; const $navbarEl = $(app.navbar.getElByPage(page)); if (!$navbarEl || $navbarEl.length === 0) return; app.navbar.size($navbarEl); }, pageInit(page) { const app = this; const $navbarEl = $(app.navbar.getElByPage(page)); if (!$navbarEl || $navbarEl.length === 0) return; // Size app.navbar.size($navbarEl); // Need Collapse On Scroll let needCollapseOnScrollHandler; if ($navbarEl.find('.title-large').length > 0) { $navbarEl.addClass('navbar-large'); } if ($navbarEl.hasClass('navbar-large')) { if (app.params.navbar.collapseLargeTitleOnScroll) needCollapseOnScrollHandler = true; page.$el.addClass('page-with-navbar-large'); } // Need transparent on scroll let needTransparentOnScroll; if (!needCollapseOnScrollHandler && $navbarEl.hasClass('navbar-transparent')) { needTransparentOnScroll = true; } // Need Hide On Scroll let needHideOnScrollHandler; if (app.params.navbar.hideOnPageScroll || page.$el.find('.hide-navbar-on-scroll').length || page.$el.hasClass('hide-navbar-on-scroll') || page.$el.find('.hide-bars-on-scroll').length || page.$el.hasClass('hide-bars-on-scroll')) { if (page.$el.find('.keep-navbar-on-scroll').length || page.$el.hasClass('keep-navbar-on-scroll') || page.$el.find('.keep-bars-on-scroll').length || page.$el.hasClass('keep-bars-on-scroll')) { needHideOnScrollHandler = false; } else { needHideOnScrollHandler = true; } } if (needCollapseOnScrollHandler || needHideOnScrollHandler || needTransparentOnScroll) { app.navbar.initNavbarOnScroll(page.el, $navbarEl[0], needHideOnScrollHandler, needCollapseOnScrollHandler, needTransparentOnScroll); } }, 'panelOpen panelSwipeOpen modalOpen': function onPanelModalOpen(instance) { const app = this; instance.$el.find('.navbar:not(.navbar-previous)').each(navbarEl => { app.navbar.size(navbarEl); }); }, tabShow(tabEl) { const app = this; $(tabEl).find('.navbar:not(.navbar-previous)').each(navbarEl => { app.navbar.size(navbarEl); }); } }, clicks: { '.navbar .title': function onTitleClick($clickedEl, clickedData, e) { const app = this; if (!app.params.navbar.scrollTopOnTitleClick) return; if ($(e.target).closest('a, button').length > 0) { return; } let $pageContentEl; // Find active page const $navbarEl = $clickedEl.parents('.navbar'); const $navbarsEl = $navbarEl.parents('.navbars'); // Static Layout $pageContentEl = $navbarEl.parents('.page-content'); if ($pageContentEl.length === 0) { // Fixed Layout if ($navbarEl.parents('.page').length > 0) { $pageContentEl = $navbarEl.parents('.page').find('.page-content'); } // Through Layout iOS if ($pageContentEl.length === 0 && $navbarsEl.length) { if ($navbarsEl.nextAll('.page-current').length > 0) { $pageContentEl = $navbarsEl.nextAll('.page-current').find('.page-content'); } } // Through Layout if ($pageContentEl.length === 0) { if ($navbarEl.nextAll('.page-current').length > 0) { $pageContentEl = $navbarEl.nextAll('.page-current').find('.page-content'); } } } if ($pageContentEl && $pageContentEl.length > 0) { // Check for tab if ($pageContentEl.hasClass('tab')) { $pageContentEl = $pageContentEl.parent('.tabs').children('.page-content.tab-active'); } if ($pageContentEl.length > 0) $pageContentEl.scrollTop(0, 300); } } }, vnode: { navbar: { postpatch(vnode) { const app = this; app.navbar.size(vnode.elm); } } } };