UNPKG

framework7-without-localstorage

Version:

Full featured mobile HTML framework for building iOS & Android apps

477 lines (453 loc) 18.8 kB
/*====================================================== ************ Panels ************ ======================================================*/ app.allowPanelOpen = true; app.openPanel = function (panelPosition, animated) { if (typeof animated === 'undefined') animated = true; if (!app.allowPanelOpen) return false; var panel = $('.panel-' + panelPosition); if (panel.length === 0 || panel.hasClass('active') || panel.hasClass('panel-visible-by-breakpoint')) return false; app.closePanel(); // Close if some panel is opened app.allowPanelOpen = false; var effect = panel.hasClass('panel-reveal') ? 'reveal' : 'cover'; panel[animated ? 'removeClass' : 'addClass']('not-animated'); panel.css({display: 'block'}).addClass('active'); panel.trigger('open panel:open'); var panelOverlay = $('.panel-overlay'); panelOverlay[animated ? 'removeClass' : 'addClass']('not-animated'); panelOverlay.show(); if (panel.find('.' + app.params.viewClass).length > 0) { if (app.sizeNavbars) app.sizeNavbars(panel.find('.' + app.params.viewClass)[0]); } // Trigger reLayout var clientLeft = panel[0].clientLeft; // Transition End; var transitionEndTarget = effect === 'reveal' ? $('.' + app.params.viewsClass) : panel; function panelTransitionEnd() { transitionEndTarget.transitionEnd(function (e) { if ($(e.target).is(transitionEndTarget)) { if (panel.hasClass('active')) { panel.trigger('opened panel:opened'); } else { panel.trigger('closed panel:closed'); } panelOverlay.css({display: ''}); app.allowPanelOpen = true; } else panelTransitionEnd(); }); } if (animated) { panelTransitionEnd(); } else { panel.trigger('opened panel:opened'); panelOverlay.css({display: ''}); app.allowPanelOpen = true; } $('body').addClass('with-panel-' + panelPosition + '-' + effect); return true; }; app.closePanel = function (animated) { if (typeof animated === 'undefined') animated = true; var activePanel = $('.panel.active'); if (activePanel.length === 0 || activePanel.hasClass('panel-visible-by-breakpoint')) return false; var effect = activePanel.hasClass('panel-reveal') ? 'reveal' : 'cover'; var panelPosition = activePanel.hasClass('panel-left') ? 'left' : 'right'; activePanel[animated ? 'removeClass' : 'addClass']('not-animated'); activePanel.removeClass('active'); var panelOverlay = $('.panel-overlay'); panelOverlay.removeClass('not-animated'); var transitionEndTarget = effect === 'reveal' ? $('.' + app.params.viewsClass) : activePanel; activePanel.trigger('close panel:close'); app.allowPanelOpen = false; if (animated) { transitionEndTarget.transitionEnd(function () { if (activePanel.hasClass('active')) return; activePanel.css({display: ''}); activePanel.trigger('closed panel:closed'); $('body').removeClass('panel-closing'); app.allowPanelOpen = true; }); $('body').addClass('panel-closing').removeClass('with-panel-' + panelPosition + '-' + effect); } else { activePanel.css({display: ''}); activePanel.trigger('closed panel:closed'); activePanel.removeClass('not-animated'); $('body').removeClass('with-panel-' + panelPosition + '-' + effect); app.allowPanelOpen = true; } }; /*====================================================== ************ Panels breakpoints ************ ======================================================*/ app.initPanelsBreakpoints = function () { var panelLeft = $('.panel-left'); var panelRight = $('.panel-right'); var views = app.root.children('.views'); var wasVisible; function setPanels() { // Left Panel if (app.params.panelLeftBreakpoint && panelLeft.length > 0) { wasVisible = panelLeft.hasClass('panel-visible-by-breakpoint'); if (app.width >= app.params.panelLeftBreakpoint) { if (!wasVisible) { $('body').removeClass('with-panel-left-reveal with-panel-left-cover'); panelLeft.css('display', '').addClass('panel-visible-by-breakpoint').removeClass('active'); panelLeft.trigger('open panel:open opened panel:opened'); views.css({ 'margin-left': panelLeft.width() + 'px' }); app.allowPanelOpen = true; } } else { if (wasVisible) { panelLeft.css('display', '').removeClass('panel-visible-by-breakpoint active'); panelLeft.trigger('close panel:close closed panel:closed'); views.css({ 'margin-left': '' }); app.allowPanelOpen = true; } } } // Right Panel if (app.params.panelRightBreakpoint && panelRight.length > 0) { wasVisible = panelRight.hasClass('panel-visible-by-breakpoint'); if (app.width >= app.params.panelRightBreakpoint) { if (!wasVisible) { $('body').removeClass('with-panel-right-reveal with-panel-right-cover'); panelRight.css('display', '').addClass('panel-visible-by-breakpoint').removeClass('active'); panelRight.trigger('open panel:open opened panel:opened'); views.css({ 'margin-right': panelRight.width() + 'px' }); app.allowPanelOpen = true; } } else { if (wasVisible) { panelRight.css('display', '').removeClass('panel-visible-by-breakpoint active'); panelRight.trigger('close panel:close closed panel:closed'); views.css({ 'margin-right': '' }); app.allowPanelOpen = true; } } } } app.onResize(setPanels); setPanels(); }; /*====================================================== ************ Swipe panels ************ ======================================================*/ app.initSwipePanels = function () { var panel, side; if (app.params.swipePanel) { panel = $('.panel.panel-' + app.params.swipePanel); side = app.params.swipePanel; if (panel.length === 0 && side !== 'both') return; } else { if (app.params.swipePanelOnlyClose) { if ($('.panel').length === 0) return; } else return; } var panelOverlay = $('.panel-overlay'); var isTouched, isMoved, isScrolling, touchesStart = {}, touchStartTime, touchesDiff, translate, overlayOpacity, opened, panelWidth, effect, direction; var views = $('.' + app.params.viewsClass); function handleTouchStart(e) { if (!app.allowPanelOpen || (!app.params.swipePanel && !app.params.swipePanelOnlyClose) || isTouched) return; if ($('.modal-in, .photo-browser-in').length > 0) return; if (!(app.params.swipePanelCloseOpposite || app.params.swipePanelOnlyClose)) { if ($('.panel.active').length > 0 && !panel.hasClass('active')) return; } if (e.target && e.target.nodeName.toLowerCase() === 'input' && e.target.type === 'range') return; if ($(e.target).closest('.tabs-swipeable-wrap').length > 0) return; touchesStart.x = e.type === 'touchstart' ? e.targetTouches[0].pageX : e.pageX; touchesStart.y = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY; if (app.params.swipePanelCloseOpposite || app.params.swipePanelOnlyClose) { if ($('.panel.active').length > 0) { side = $('.panel.active').hasClass('panel-left') ? 'left' : 'right'; } else { if (app.params.swipePanelOnlyClose) return; side = app.params.swipePanel; } if (!side) return; } panel = $('.panel.panel-' + side); opened = panel.hasClass('active'); if (app.params.swipePanelActiveArea && !opened) { if (side === 'left') { if (touchesStart.x > app.params.swipePanelActiveArea) return; } if (side === 'right') { if (touchesStart.x < app.width - app.params.swipePanelActiveArea) return; } } isMoved = false; isTouched = true; isScrolling = undefined; touchStartTime = (new Date()).getTime(); direction = undefined; } function handleTouchMove(e) { if (!isTouched) return; if (e.f7PreventPanelSwipe) return; var pageX = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX; var pageY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY; if (typeof isScrolling === 'undefined') { isScrolling = !!(isScrolling || Math.abs(pageY - touchesStart.y) > Math.abs(pageX - touchesStart.x)); } if (isScrolling) { isTouched = false; return; } if (!direction) { if (pageX > touchesStart.x) { direction = 'to-right'; } else { direction = 'to-left'; } if(side === 'both'){ if ($('.panel.active').length > 0) { side = $('.panel.active').hasClass('panel-left') ? 'left' : 'right'; } else { side = direction === 'to-right' ? 'left' : 'right'; } if (app.params.swipePanelActiveArea > 0) { if (side === 'left' && touchesStart.x > app.params.swipePanelActiveArea) { isTouched = false; return; } if (side === 'right' && touchesStart.x < app.width - app.params.swipePanelActiveArea) { isTouched = false; return; } } panel = $('.panel.panel-' + side); } if (panel.hasClass('panel-visible-by-breakpoint')) { isTouched = false; return; } if ( side === 'left' && ( direction === 'to-left' && !panel.hasClass('active') ) || side === 'right' && ( direction === 'to-right' && !panel.hasClass('active') ) ) { isTouched = false; return; } } if (app.params.swipePanelNoFollow) { var timeDiff = (new Date()).getTime() - touchStartTime; if (timeDiff < 300) { if (direction === 'to-left') { if (side === 'right') app.openPanel(side); if (side === 'left' && panel.hasClass('active')) app.closePanel(); } if (direction === 'to-right') { if (side === 'left') app.openPanel(side); if (side === 'right' && panel.hasClass('active')) app.closePanel(); } } isTouched = false; isMoved = false; return; } if (!isMoved) { effect = panel.hasClass('panel-cover') ? 'cover' : 'reveal'; if (!opened) { panel.show(); panelOverlay.show(); } panelWidth = panel[0].offsetWidth; panel.transition(0); if (panel.find('.' + app.params.viewClass).length > 0) { if (app.sizeNavbars) app.sizeNavbars(panel.find('.' + app.params.viewClass)[0]); } } isMoved = true; e.preventDefault(); var threshold = opened ? 0 : -app.params.swipePanelThreshold; if (side === 'right') threshold = -threshold; touchesDiff = pageX - touchesStart.x + threshold; if (side === 'right') { if (effect === 'cover') { translate = touchesDiff + (opened ? 0 : panelWidth); if (translate < 0) translate = 0; if (translate > panelWidth) { translate = panelWidth; } } else { translate = touchesDiff - (opened ? panelWidth : 0); if (translate > 0) translate = 0; if (translate < -panelWidth) { translate = -panelWidth; } } } else { translate = touchesDiff + (opened ? panelWidth : 0); if (translate < 0) translate = 0; if (translate > panelWidth) { translate = panelWidth; } } if (effect === 'reveal') { views.transform('translate3d(' + translate + 'px,0,0)').transition(0); panelOverlay.transform('translate3d(' + translate + 'px,0,0)').transition(0); panel.trigger('panel:swipe', {progress: Math.abs(translate / panelWidth)}); app.pluginHook('swipePanelSetTransform', views[0], panel[0], Math.abs(translate / panelWidth)); } else { if (side === 'left') translate = translate - panelWidth; panel.transform('translate3d(' + (translate) + 'px,0,0)').transition(0); panelOverlay.transition(0); overlayOpacity = 1 - Math.abs(translate/panelWidth); panelOverlay.css({opacity: overlayOpacity}); panel.trigger('panel:swipe', {progress: Math.abs(translate / panelWidth)}); app.pluginHook('swipePanelSetTransform', views[0], panel[0], Math.abs(translate / panelWidth)); } } function handleTouchEnd(e) { if (!isTouched || !isMoved) { isTouched = false; isMoved = false; return; } isTouched = false; isMoved = false; var timeDiff = (new Date()).getTime() - touchStartTime; var action; var edge = (translate === 0 || Math.abs(translate) === panelWidth); if (!opened) { if (effect === 'cover') { if (translate === 0) { action = 'swap'; //open } else if (timeDiff < 300 && Math.abs(translate) > 0) { action = 'swap'; //open } else if (timeDiff >= 300 && Math.abs(translate) < panelWidth / 2) { action = 'swap'; //open } else { action = 'reset'; //close } } else { if (translate === 0) { action = 'reset'; } else if ( timeDiff < 300 && Math.abs(translate) > 0 || timeDiff >= 300 && (Math.abs(translate) >= panelWidth / 2) ) { action = 'swap'; } else { action = 'reset'; } } } else { if (effect === 'cover') { if (translate === 0) { action = 'reset'; //open } else if (timeDiff < 300 && Math.abs(translate) > 0) { action = 'swap'; //open } else if (timeDiff >= 300 && Math.abs(translate) < panelWidth / 2) { action = 'reset'; //open } else { action = 'swap'; //close } } else { if (translate === -panelWidth) { action = 'reset'; } else if ( timeDiff < 300 && Math.abs(translate) >= 0 || timeDiff >= 300 && (Math.abs(translate) <= panelWidth / 2) ) { if (side === 'left' && translate === panelWidth) action = 'reset'; else action = 'swap'; } else { action = 'reset'; } } } if (action === 'swap') { app.allowPanelOpen = true; if (opened) { app.closePanel(); if (edge) { panel.css({display: ''}); $('body').removeClass('panel-closing'); } } else { app.openPanel(side); } if (edge) app.allowPanelOpen = true; } if (action === 'reset') { if (opened) { app.allowPanelOpen = true; app.openPanel(side); } else { app.closePanel(); if (edge) { app.allowPanelOpen = true; panel.css({display: ''}); } else { var target = effect === 'reveal' ? views : panel; panel.trigger('close panel:close'); $('body').addClass('panel-closing'); target.transitionEnd(function () { if (panel.hasClass('active')) return; panel.trigger('close panel:closed'); panel.css({display: ''}); $('body').removeClass('panel-closing'); app.allowPanelOpen = true; }); } } } if (effect === 'reveal') { views.transition(''); views.transform(''); } panel.transition('').transform(''); panelOverlay.css({display: ''}).transform('').transition('').css('opacity', ''); } var passiveListener = app.touchEvents.start === 'touchstart' && app.support.passiveListener ? {passive: true, capture: false} : false; var activeListener = app.support.passiveListener ? {passive: false, capture: false} : false; $(document).on(app.touchEvents.start, handleTouchStart, passiveListener); $(document).on(app.touchEvents.move, handleTouchMove, activeListener); $(document).on(app.touchEvents.end, handleTouchEnd, passiveListener); };