123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683 |
- (function($){
- /**
- * Helper class for header layout logic.
- *
- * @since 1.0
- * @class FLThemeBuilderHeaderLayout
- */
- FLThemeBuilderHeaderLayout = {
- /**
- * A reference to the window object for this page.
- *
- * @since 1.0
- * @property {Object} win
- */
- win : null,
- /**
- * A reference to the body object for this page.
- *
- * @since 1.0
- * @property {Object} body
- */
- body : null,
- /**
- * A reference to the header object for this page.
- *
- * @since 1.0
- * @property {Object} header
- */
- header : null,
- /**
- * Whether this header overlays the content or not.
- *
- * @since 1.0
- * @property {Boolean} overlay
- */
- overlay : false,
- /**
- * Whether the page has the WP admin bar or not.
- *
- * @since 1.0
- * @property {Boolean} hasAdminBar
- */
- hasAdminBar : false,
- /**
- * Breakpoint for when the sticky header should apply.
- *
- * @since 1.4
- * @property {String} stickyOn
- */
- stickyOn: '',
- /**
- * A reference of the sticky and shrink header breakpoint.
- *
- * @since 1.2.5
- * @property {Number} breakpointWidth
- */
- breakpointWidth: 0,
- /**
- * Initializes header layout logic.
- *
- * @since 1.0
- * @method init
- */
- init: function()
- {
- var editing = $( 'html.fl-builder-edit' ).length,
- header = $( '.fl-builder-content[data-type=header]' ),
- menuModule = header.find( '.fl-module-menu' ),
- breakpoint = null;
- if ( ! editing && header.length ) {
- header.imagesLoaded( $.proxy( function() {
- this.win = $( window );
- this.body = $( 'body' );
- this.header = header.eq( 0 );
- this.overlay = !! Number( header.attr( 'data-overlay' ) );
- this.hasAdminBar = !! $( 'body.admin-bar' ).length;
- this.stickyOn = this.header.data( 'sticky-on' );
- breakpoint = this.header.data( 'sticky-breakpoint' );
- if ( '' == this.stickyOn ) {
- if ( typeof FLBuilderLayoutConfig.breakpoints[ breakpoint ] !== undefined ) {
- this.breakpointWidth = FLBuilderLayoutConfig.breakpoints[ breakpoint ];
- }
- else {
- this.breakpointWidth = FLBuilderLayoutConfig.breakpoints.medium;
- }
- }
- if ( Number( header.attr( 'data-sticky' ) ) ) {
- this.header.data( 'original-top', this.header.offset().top );
- this.win.on( 'resize', $.throttle( 500, $.proxy( this._initSticky, this ) ) );
- this._initSticky();
- }
- }, this ) );
- }
- },
- /**
- * Initializes sticky logic for a header.
- *
- * @since 1.0
- * @access private
- * @method _initSticky
- */
- _initSticky: function( e )
- {
- var header = $('.fl-builder-content[data-type=header]'),
- windowSize = this.win.width(),
- makeSticky = false;
- makeSticky = this._makeWindowSticky( windowSize );
- if ( makeSticky || ( this.breakpointWidth > 0 && windowSize >= this.breakpointWidth ) ) {
- this.win.on( 'scroll.fl-theme-builder-header-sticky', $.proxy( this._doSticky, this ) );
- //
- // Check if Event Type is 'resize' then invoke this._doSticky()
- // only if the 'fl-theme-builder-header-sticky' class is already present.
- //
- if ( e && 'resize' === e.type ) {
- if ( this.header.hasClass( 'fl-theme-builder-header-sticky' ) ) {
- this._doSticky( e );
- }
- this._adjustStickyHeaderWidth();
- }
- if ( Number( header.attr( 'data-shrink' ) ) ) {
- this.header.data( 'original-height', this.header.outerHeight() );
- this.win.on( 'resize', $.throttle( 500, $.proxy( this._initShrink, this ) ) );
- this._initShrink();
- }
- this._initFlyoutMenuFix( e );
- } else {
- this.win.off( 'scroll.fl-theme-builder-header-sticky' );
- this.win.off( 'resize.fl-theme-builder-header-sticky' );
- this.header.removeClass( 'fl-theme-builder-header-sticky' );
- this.header.removeAttr( 'style' );
- this.header.parent().css( 'padding-top', '0' );
- }
- },
- /**
- * Check if Header should be sticky at a particular Window size.
- *
- * @since 1.4
- * @access private
- * @param widowSize
- * @method _makeWindowSticky
- */
- _makeWindowSticky: function ( windowSize )
- {
- var makeSticky = false;
- switch (this.stickyOn) {
- case 'xl':
- makeSticky = windowSize > FLBuilderLayoutConfig.breakpoints['large'];
- break;
- case '': // Default
- case 'desktop':
- makeSticky = windowSize >= FLBuilderLayoutConfig.breakpoints['medium'];
- break;
- case 'desktop-medium':
- makeSticky = windowSize > FLBuilderLayoutConfig.breakpoints['small'];
- break;
- case 'large':
- makeSticky = windowSize > FLBuilderLayoutConfig.breakpoints['medium'] && windowSize <= FLBuilderLayoutConfig.breakpoints['large'];
- break;
- case 'large-medium':
- makeSticky = windowSize > FLBuilderLayoutConfig.breakpoints['small'] && windowSize <= FLBuilderLayoutConfig.breakpoints['large'];
- break;
- case 'medium':
- makeSticky = ( windowSize <= FLBuilderLayoutConfig.breakpoints['medium'] && windowSize > FLBuilderLayoutConfig.breakpoints['small'] );
- break;
- case 'medium-mobile':
- makeSticky = (windowSize <= FLBuilderLayoutConfig.breakpoints['medium']);
- break;
- case 'mobile':
- makeSticky = (windowSize <= FLBuilderLayoutConfig.breakpoints['small']);
- break;
- case 'all':
- makeSticky = true;
- break;
- }
- return makeSticky;
- },
- /**
- * Sticks the header when the page is scrolled.
- *
- * @since 1.0
- * @access private
- * @method _doSticky
- */
- _doSticky: function( e )
- {
- var winTop = Math.floor( this.win.scrollTop() ),
- headerTop = Math.floor( this.header.data( 'original-top' ) ),
- hasStickyClass = this.header.hasClass( 'fl-theme-builder-header-sticky' ),
- hasScrolledClass = this.header.hasClass( 'fl-theme-builder-header-scrolled' ),
- beforeHeader = this.header.prevAll( '.fl-builder-content' ),
- bodyTopPadding = parseInt( jQuery('body').css('padding-top') ),
- winBarHeight = $('#wpadminbar').length ? $('#wpadminbar').outerHeight() : 0,
- headerHeight = 0;
- if ( isNaN( bodyTopPadding ) ) {
- bodyTopPadding = 0;
- }
- if ( this.hasAdminBar && this.win.width() > 600 ) {
- winTop += Math.floor( winBarHeight );
- }
- if ( winTop > headerTop ) {
- if ( ! hasStickyClass ) {
- if ( e && ( 'scroll' === e.type || 'smartscroll' === e.type ) ) {
- this.header.addClass( 'fl-theme-builder-header-sticky' );
- if ( this.overlay && beforeHeader.length ) {
- this.header.css( 'top', winBarHeight);
- }
- }
- if ( ! this.overlay ) {
- this._adjustHeaderHeight();
- }
- }
- }
- else if ( hasStickyClass ) {
- this.header.removeClass( 'fl-theme-builder-header-sticky' );
- this.header.removeAttr( 'style' );
- this.header.parent().css( 'padding-top', '0' );
- }
- this._adjustStickyHeaderWidth();
- if ( winTop > headerTop ) {
- if ( ! hasScrolledClass ) {
- this.header.addClass( 'fl-theme-builder-header-scrolled' );
- }
- } else if ( hasScrolledClass ) {
- this.header.removeClass( 'fl-theme-builder-header-scrolled' );
- }
- this._flyoutMenuFix( e );
- },
- /**
- * Initializes flyout menu fixes on sticky header.
- *
- * @since 1.4.1
- * @method _initFlyoutMenuFix
- */
- _initFlyoutMenuFix: function( e ) {
- var header = this.header,
- menuModule = header.find( '.fl-menu' ),
- flyoutMenu = menuModule.find( '.fl-menu-mobile-flyout' ),
- isPushMenu = menuModule.hasClass( 'fl-menu-responsive-flyout-push' ) || menuModule.hasClass( 'fl-menu-responsive-flyout-push-opacity' ),
- isSticky = header.hasClass( 'fl-theme-builder-header-sticky' ),
- isOverlay = menuModule.hasClass( 'fl-menu-responsive-flyout-overlay' ),
- flyoutPos = menuModule.hasClass( 'fl-flyout-right' ) ? 'right' : 'left',
- flyoutParent = header.parent().is( 'header' ) ? header.parent().parent() : header.parent();
- isFullWidth = this.win.width() === header.width(),
- flyoutLayout = '',
- activePos = 250,
- headerPos = 0;
- if ( ! flyoutMenu.length ) {
- return;
- }
- if ( this.win.width() > header.parent().width() ) {
- headerPos = ( this.win.width() - header.width() ) / 2;
- }
- if ( isOverlay ) {
- activePos = headerPos;
- }
- else if ( isPushMenu ) {
- activePos = activePos + headerPos;
- }
- flyoutMenu.data( 'activePos', activePos );
- if ( isPushMenu ) {
- flyoutLayout = 'push-' + flyoutPos;
- }
- else if ( isOverlay ) {
- flyoutLayout = 'overlay-' + flyoutPos;
- }
- if ( isPushMenu && ! $( 'html' ).hasClass( 'fl-theme-builder-has-flyout-menu' ) ) {
- $( 'html' ).addClass( 'fl-theme-builder-has-flyout-menu' );
- }
- if ( ! flyoutParent.hasClass( 'fl-theme-builder-flyout-menu-' + flyoutLayout ) ) {
- flyoutParent.addClass( 'fl-theme-builder-flyout-menu-' + flyoutLayout );
- }
- if ( ! header.hasClass( 'fl-theme-builder-flyout-menu-overlay' ) && isOverlay ) {
- header.addClass( 'fl-theme-builder-flyout-menu-overlay' );
- }
- if ( ! header.hasClass( 'fl-theme-builder-header-full-width' ) && isFullWidth ) {
- header.addClass( 'fl-theme-builder-header-full-width' );
- }
- else if ( ! isFullWidth ) {
- header.removeClass( 'fl-theme-builder-header-full-width' );
- }
- menuModule.on( 'click', '.fl-menu-mobile-toggle', $.proxy( function( event ){
- if ( menuModule.find( '.fl-menu-mobile-toggle.fl-active' ).length ) {
- $( 'html' ).addClass( 'fl-theme-builder-flyout-menu-active' );
- event.stopImmediatePropagation();
- }
- else {
- $( 'html' ).removeClass( 'fl-theme-builder-flyout-menu-active' );
- }
- this._flyoutMenuFix( event );
- }, this ) );
- },
- /**
- * Fix flyout menu inside the sticky header.
- *
- * @since 1.4.1
- * @method _flyoutMenuFix
- */
- _flyoutMenuFix: function( e ){
- var header = this.header,
- menuModule = header.find( '.fl-menu' ),
- flyoutMenu = menuModule.find( '.fl-menu-mobile-flyout' ),
- isPushMenu = menuModule.hasClass( 'fl-menu-responsive-flyout-push' ) || menuModule.hasClass( 'fl-menu-responsive-flyout-push-opacity' ),
- flyoutPos = menuModule.hasClass( 'fl-flyout-right' ) ? 'right' : 'left',
- menuOpacity = menuModule.find( '.fl-menu-mobile-opacity' ),
- isScroll = 'undefined' !== typeof e && 'scroll' === e.handleObj.type,
- activePos = 'undefined' !== typeof flyoutMenu.data( 'activePos' ) ? flyoutMenu.data( 'activePos' ) : 0,
- headerPos = ( this.win.width() - header.width() ) / 2,
- inactivePos = headerPos > 0 ? activePos + 4 : 254;
- if ( ! flyoutMenu.length ) {
- return;
- }
- if ( this.overlay ) {
- return;
- }
- if( $( '.fl-theme-builder-flyout-menu-active' ).length ) {
- if ( isScroll && ! flyoutMenu.hasClass( 'fl-menu-disable-transition' ) ) {
- flyoutMenu.addClass( 'fl-menu-disable-transition' );
- }
- if ( header.hasClass( 'fl-theme-builder-header-sticky' ) ) {
- if ( ! isScroll ) {
- setTimeout( $.proxy( function(){
- flyoutMenu.css( flyoutPos, '-' + activePos + 'px' );
- }, this ), 1 );
- }
- else {
- flyoutMenu.css( flyoutPos, '-' + activePos + 'px' );
- }
- }
- else {
- flyoutMenu.css( flyoutPos, '0px' );
- }
- }
- else {
- if ( flyoutMenu.hasClass( 'fl-menu-disable-transition' ) ) {
- flyoutMenu.removeClass( 'fl-menu-disable-transition' );
- }
- if ( header.hasClass( 'fl-theme-builder-flyout-menu-overlay' ) && headerPos > 0 && headerPos < 250 ) {
- if ( header.hasClass( 'fl-theme-builder-header-sticky' ) ) {
- inactivePos = headerPos + 254;
- }
- else {
- inactivePos = 254;
- }
- }
- if ( e && e.type === 'resize' ) {
- inactivePos = headerPos + 254;
- }
- flyoutMenu.css( flyoutPos, '-' + inactivePos + 'px' );
- }
- if ( e && menuModule.is('.fl-menu-responsive-flyout-overlay') && $.infinitescroll ) {
- e.stopImmediatePropagation();
- }
- if( menuOpacity.length ) {
- if ( header.hasClass( 'fl-theme-builder-header-sticky' ) ) {
- if ( '0px' === menuOpacity.css( 'left' ) ) {
- menuOpacity.css( 'left', '-' + headerPos + 'px' );
- }
- }
- else {
- menuOpacity.css( 'left', '' );
- }
- }
- },
- /**
- * Adjust sticky header width if BB Theme Boxed Layout is used.
- *
- * @since 1.4
- * @access private
- * @method _adjustStickyHeaderWidth
- */
- _adjustStickyHeaderWidth: function () {
- if ( $('body').hasClass( 'fl-fixed-width' ) ) {
- var parentWidth = this.header.parent().width();
- // Better if this is set in the stylesheet file.
- if ( this.win.width() >= 992 ) {
- this.header.css({
- 'margin': '0 auto',
- 'max-width': parentWidth,
- });
- }
- else {
- this.header.css({
- 'margin': '',
- 'max-width': '',
- });
- }
- }
- },
- /**
- * Adjust Sticky Header Height
- *
- * @since 1.4
- * @access private
- * @method _adjustHeaderHeight
- */
- _adjustHeaderHeight: function () {
- var beforeHeader = this.header.prevAll('.fl-builder-content'),
- beforeHeaderHeight = 0,
- beforeHeaderFix = 0,
- headerHeight = Math.floor( this.header.outerHeight() ),
- bodyTopPadding = parseInt( $( 'body' ).css( 'padding-top' ) ),
- wpAdminBarHeight = 0,
- totalHeaderHeight = 0;
- if ( isNaN( bodyTopPadding ) ) {
- bodyTopPadding = 0;
- }
- if ( beforeHeader.length ) {
- $.each( beforeHeader, function() {
- beforeHeaderHeight += Math.floor( $(this).outerHeight() );
- });
- // Subtract this value from the header parent's top padding.
- beforeHeaderFix = 2;
- }
- if ( this.hasAdminBar && this.win.width() <= 600 ) {
- wpAdminBarHeight = Math.floor( $('#wpadminbar').outerHeight() );
- }
- totalHeaderHeight = Math.floor( beforeHeaderHeight + headerHeight);
- if ( headerHeight > 0 ) {
- var headerParent = this.header.parent(),
- headerParentTopPadding = 0;
- // If the header's parent container is the BODY tag ignore its top padding.
- if ( $( headerParent ).is('body') ) {
- headerParentTopPadding = Math.floor( headerHeight - wpAdminBarHeight );
- } else {
- headerParentTopPadding = Math.floor( headerHeight - bodyTopPadding - wpAdminBarHeight );
- }
- $( headerParent ).css( 'padding-top', ( headerParentTopPadding - beforeHeaderFix ) + 'px' );
- this.header.css({
- '-webkit-transform': 'translate(0px, -' + totalHeaderHeight + 'px)',
- '-ms-transform': 'translate(0px, -' + totalHeaderHeight + 'px)',
- 'transform': 'translate(0px, -' + totalHeaderHeight + 'px)'
- });
- }
- },
- /**
- * Initializes shrink logic for a header.
- *
- * @since 1.0
- * @access private
- * @method _initShrink
- */
- _initShrink: function( e )
- {
- if ( this.win.width() >= this.breakpointWidth ) {
- this.win.on( 'scroll.fl-theme-builder-header-shrink', $.proxy( this._doShrink, this ) );
- this._setImageMaxHeight();
- if ( this.win.scrollTop() > 0 ){
- this._doShrink();
- }
- } else {
- this.header.parent().css( 'padding-top', '0' );
- this.win.off( 'scroll.fl-theme-builder-header-shrink' );
- this._removeShrink();
- this._removeImageMaxHeight();
- }
- },
- /**
- * Shrinks the header when the page is scrolled.
- *
- * @since 1.0
- * @access private
- * @method _doShrink
- */
- _doShrink: function( e )
- {
- var winTop = this.win.scrollTop(),
- headerTop = this.header.data('original-top'),
- headerHeight = this.header.data('original-height'),
- shrinkImageHeight = this.header.data('shrink-image-height'),
- windowSize = this.win.width(),
- makeSticky = this._makeWindowSticky( windowSize ),
- hasClass = this.header.hasClass( 'fl-theme-builder-header-shrink' );
- if ( this.hasAdminBar ) {
- winTop += 32;
- }
- if ( makeSticky && ( winTop > headerTop + headerHeight ) ) {
- if ( ! hasClass ) {
- this.header.addClass( 'fl-theme-builder-header-shrink' );
- // Shrink images but don't include lightbox and menu images.
- this.header.find('img').each( function( i ) {
- var image = $( this ),
- maxMegaMenu = image.closest( '.max-mega-menu' ).length,
- imageInLightbox = image.closest( '.fl-button-lightbox-content' ).length,
- imageInNavMenu = image.closest( 'li.menu-item' ).length;
- if ( ! ( imageInLightbox || imageInNavMenu || maxMegaMenu ) ) {
- image.css( 'max-height', shrinkImageHeight );
- }
- });
- this.header.find( '.fl-row-content-wrap' ).each( function() {
- var row = $( this );
- if ( parseInt( row.css( 'padding-bottom' ) ) > 5 ) {
- row.addClass( 'fl-theme-builder-header-shrink-row-bottom' );
- }
- if ( parseInt( row.css( 'padding-top' ) ) > 5 ) {
- row.addClass( 'fl-theme-builder-header-shrink-row-top' );
- }
- } );
- this.header.find( '.fl-module-content' ).each( function() {
- var module = $( this );
- if ( parseInt( module.css( 'margin-bottom' ) ) > 5 ) {
- module.addClass( 'fl-theme-builder-header-shrink-module-bottom' );
- }
- if ( parseInt( module.css( 'margin-top' ) ) > 5 ) {
- module.addClass( 'fl-theme-builder-header-shrink-module-top' );
- }
- } );
- }
- } else if (hasClass) {
- this.header.find( 'img' ).css( 'max-height', '' );
- this._removeShrink();
- }
- // Fixes Shrink header issue with BB Theme when window is scrolled then resized and back.
- if ( 'undefined' === typeof( e ) && $('body').hasClass( 'fl-fixed-width' ) ) {
- if ( ! this.overlay ) {
- this._adjustHeaderHeight();
- }
- }
- },
- /**
- * Removes the header shrink effect.
- *
- * @since 1.0
- * @access private
- * @method _removeShrink
- */
- _removeShrink: function()
- {
- var rows = this.header.find( '.fl-row-content-wrap' ),
- modules = this.header.find( '.fl-module-content' );
- rows.removeClass( 'fl-theme-builder-header-shrink-row-bottom' );
- rows.removeClass( 'fl-theme-builder-header-shrink-row-top' );
- modules.removeClass( 'fl-theme-builder-header-shrink-module-bottom' );
- modules.removeClass( 'fl-theme-builder-header-shrink-module-top' );
- this.header.removeClass( 'fl-theme-builder-header-shrink' );
- },
- /**
- * Adds max height to images in modules for smooth scrolling.
- *
- * @since 1.1.1
- * @access private
- * @method _setImageMaxHeight
- */
- _setImageMaxHeight: function()
- {
- var head = $( 'head' ),
- stylesId = 'fl-header-styles-' + this.header.data( 'post-id' ),
- styles = '',
- images = this.header.find( '.fl-module-content img' );
- if ( $( '#' + stylesId ).length ) {
- return;
- }
- images.each( function( i ) {
- var image = $( this ),
- height = image.height(),
- node = image.closest( '.fl-module' ).data( 'node' ),
- className = 'fl-node-' + node + '-img-' + i,
- maxMegaMenu = image.closest( '.max-mega-menu' ).length,
- imageInLightbox = image.closest( '.fl-button-lightbox-content' ).length,
- imageInNavMenu = image.closest( 'li.menu-item' ).length;
- if ( ! ( imageInLightbox || imageInNavMenu || maxMegaMenu ) ) {
- image.addClass( className );
- styles += '.' + className + ' { max-height: ' + ( height ? height : image[0].height ) + 'px }';
- }
- } );
- if ( '' !== styles ) {
- head.append( '<style id="' + stylesId + '">' + styles + '</style>' );
- }
- },
- /**
- * Removes max height on images in modules for smooth scrolling.
- *
- * @since 1.1.1
- * @access private
- * @method _removeImageMaxHeight
- */
- _removeImageMaxHeight: function()
- {
- $( '#fl-header-styles-' + this.header.data( 'post-id' ) ).remove();
- },
- };
- $( function() { FLThemeBuilderHeaderLayout.init(); } );
- })(jQuery);
|