1(function($){ 2 3 /** 4 * Helper class for frontend theme logic. 5 * 6 * @since 1.0 7 * @class FLTheme 8 */ 9 FLTheme = { 10 11 /** 12 * Initializes all frontend theme logic. 13 * 14 * @since 1.0 15 * @method init 16 */ 17 init: function() 18 { 19 this._bind(); 20 }, 21 22 /** 23 * Initializes and binds all frontend events. 24 * 25 * @since 1.0 26 * @access private 27 * @method _bind 28 */ 29 _bind: function() 30 { 31 var self = this; 32 33 // Nav Toggles 34 $('.navbar-toggle').on('click', this.navbarToggleClick); 35 36 // Top Nav Drop Downs 37 if($('.fl-page-bar-nav ul.sub-menu').length != 0) { 38 this._setupDropDowns(); 39 this._enableTopNavDropDowns(); 40 } 41 42 // Page Nav Drop downs 43 if($('.fl-page-nav ul.sub-menu').length != 0) { 44 $(window).on('resize.fl-page-nav-sub-menu', $.throttle(500, this._enablePageNavDropDowns)); 45 this._setupDropDowns(); 46 this._enablePageNavDropDowns(); 47 } 48 49 // Current menu item initializes or click 50 if($('.fl-page-nav ul.menu').length != 0) { 51 $('.fl-page-nav ul.menu').find('.menu-item').on('click', '> a[href*="#"]:not([href="#"])', this._setupCurrentNavItem); 52 this._setupCurrentNavItem(); 53 } 54 55 // Nav Search 56 if($('.fl-page-nav-search').length != 0) { 57 $('.fl-page-nav-search a.fa-search').on('click', this._toggleNavSearch); 58 } 59 60 // Nav vertical 61 if($('.fl-nav-vertical').length != 0) { 62 $(window).on('resize', $.throttle(500, this._navVertical)); 63 this._navVertical(); 64 } 65 66 // Nav vertical right & boxed layout 67 if($('.fl-fixed-width.fl-nav-vertical-right').length != 0) { 68 $(window).on('resize', $.throttle(500, this._updateVerticalRightPos)); 69 this._updateVerticalRightPos(); 70 } 71 72 // Centered inline logo 73 if($('.fl-page-nav-centered-inline-logo').length != 0) { 74 $(window).on('resize', $.throttle(500, this._centeredInlineLogo)); 75 this._centeredInlineLogo(); 76 } 77 78 // Nav Left 79 if($('body.fl-nav-left').length != 0) { 80 $(window).on('resize', $.throttle(500, this._navLeft)); 81 this._navLeft(); 82 } 83 84 // Shrink Header 85 if( ($('body.fl-shrink').length != 0) && !($('html.fl-builder-edit').length != 0) ) { 86 $(window).on('resize', $.throttle(500, this._shrinkHeaderEnable)); 87 this._shrinkHeaderInit(); 88 this._shrinkHeaderEnable(); 89 } 90 91 // Fixed Header (Fade In) 92 if($('.fl-page-header-fixed').length != 0) { 93 $(window).on('resize.fl-page-header-fixed', $.throttle(500, this._enableFixedHeader)); 94 this._enableFixedHeader(); 95 } 96 97 // Fixed Header (Fixed) 98 if( ($('body.fl-fixed-header').length != 0) && !($('html.fl-builder-edit').length != 0) ) { 99 $(window).on('resize', $.throttle(500, this._fixedHeader)); 100 this._fixedHeader(); 101 } 102 103 // Hide Header Until Scroll 104 if( ($('body.fl-scroll-header').length != 0) && !($('html.fl-builder-edit').length != 0) ) { 105 $(window).on('resize', $.throttle(500, this._scrollHeader)); 106 this._scrollHeader(); 107 } 108 109 // Mega Menu (Primary Nav) 110 if($('.fl-page-header-primary').find( 'li.mega-menu' ).length != 0) { 111 $(window).on('resize', $.throttle(500, this._megaMenu)); 112 this._megaMenu(); 113 } 114 115 // Mega Menu (Fixed) 116 if($('.fl-page-header-fixed').length != 0) { 117 $(window).on('scroll.fl-mega-menu-on-scroll', $.throttle(500, this._megaMenuOnScroll)); 118 $(window).on('resize.fl-mega-menu-on-scroll', $.throttle(500, this._megaMenuOnScroll)); 119 } 120 121 // Headers not be fixed when the builder is active 122 if($('html.fl-builder-edit').length != 0) { 123 this._fixedHeadersWhenBuilderActive(); 124 } 125 126 // Responsive Nav Layout 127 if ( $( 'body.fl-nav-mobile-offcanvas' ).length != 0 && ! $( 'html.fl-builder-edit' ).length != 0 ) { 128 $(window).on('resize', $.throttle(500, this._setupMobileNavLayout)); 129 this._setupMobileNavLayout(); 130 this._toggleMobileNavLayout(); 131 } 132 133 // Close Dropdown or Flyout Menu 134 $( 'body' ).on( 'click', this.closeMenu ); 135 136 // Close Dropdown or Flyout Menu when tabbing out from the last menu item. 137 $( '.fl-theme-menu > li:last-child' ).on( 'focusout', function (e) { 138 if ( undefined === $(e.relatedTarget)[0] || 'nav-link' !== $(e.relatedTarget)[0].className) { 139 self.closeMenu( e ); 140 } 141 }); 142 143 // Footer parallax effect 144 if($('.fl-full-width.fl-footer-effect').length != 0) { 145 $(window).on('resize', $.throttle(500, this._footerEffect)); 146 this._footerEffect(); 147 } 148 149 // Go to Top 150 if($('body.fl-scroll-to-top').length != 0) {
151 this._toTop(); 152 } 153 154 // Lightbox 155 if(typeof $('body').magnificPopup != 'undefined') { 156 this._enableLightbox(); 157 } 158 159 // FitVids 160 if(typeof $.fn.fitVids != 'undefined' && !$('body').hasClass('fl-builder')) { 161 this._enableFitVids(); 162 } 163 FLTheme._navBackiosFix(); 164 165 // Smooth scrolling. 166 this._initSmoothScroll() 167 }, 168 169 /** 170 * Checks to see if the current device is mobile. 171 * 172 * @since 1.5.1 173 * @access private 174 * @method _isMobile 175 * @return {Boolean} 176 */ 177 _isMobile: function() 178 { 179 if ( ( 'ontouchstart' in window ) || ( navigator.maxTouchPoints > 0 ) || ( navigator.msMaxTouchPoints > 0 ) ) { 180 return true; 181 } 182 183 return /Mobile|Android|Silk\/|Kindle|BlackBerry|Opera Mini|Opera Mobi|webOS/i.test( navigator.userAgent ); 184 }, 185 186 /** 187 * Initializes retina images. 188 * 189 * @since 1.0 190 * @access private 191 * @method _initRetinaImages 192 */ 193 _initRetinaImages: function() 194 { 195 var pixelRatio = !!window.devicePixelRatio ? window.devicePixelRatio : 1; 196 197 if ( pixelRatio > 1 ) { 198 $( 'img[data-retina]' ).each( FLTheme._convertImageToRetina ); 199 } 200 }, 201 202 /** 203 * Converts an image to retina. 204 * 205 * @since 1.0 206 * @access private 207 * @method _convertImageToRetina 208 */ 209 _convertImageToRetina: function() 210 { 211 var image = $( this ), 212 tmpImage = new Image(), 213 src = image.attr( 'src' ), 214 retinaSrc = image.data( 'retina' ) 215 216 // check for cloudflare 217 if( typeof src == 'undefined') { 218 src = image.data( 'cfsrc' ) 219 } 220 221 // still no src, bail. 222 if( typeof src == 'undefined') { 223 return false; 224 } 225 226 var type = src.split('.').pop(); 227 228 if ( '' != retinaSrc ) { 229 230 tmpImage.onload = function() { 231 var width = tmpImage.width, 232 height = tmpImage.height; 233 234 if ( 'svg' == type ) { 235 width = image.width(); 236 height = image.height(); 237 } 238 239 //image.css( 'max-height', height ); 240 image.width( width ); 241 image.attr( 'src', retinaSrc ); 242 }; 243 244 tmpImage.src = src; 245 } 246 }, 247 248 /** 249 * Mobile Header Logo. 250 * 251 * @since 1.7 252 * @access private 253 * @method _initMobileHeaderLogo 254 */ 255 _initMobileHeaderLogo: function() 256 { 257 this._enableMobileLogo(); 258 $( window ).on( 'resize', $.proxy( this._enableMobileLogo, this ) ); 259 }, 260 261 /** 262 * Enable Mobile Logo. 263 * 264 * @since 1.7 265 * @access private 266 * @method _enableMobileLogo 267 */ 268 _enableMobileLogo: function() 269 { 270 var win = $( window ), 271 logoWrap = $( '.fl-page-header-logo' ), 272 logos = logoWrap.find( 'img[data-mobile]' ), 273 image = null, 274 mobileSrc = null, 275 tmpImage = null; 276 277 if ( 0 === logos.length ) { 278 return; 279 } 280 281 $( logos ).each( function(){ 282 tmpImage = new Image(); 283 image = $( this ); 284 src = image.attr( 'src' ); 285 width = image.data( 'width' ); 286 height = image.data( 'height' ); 287 mobileSrc = image.data( 'mobile' ); 288 mobileWidth = image.data( 'mobile-width' ); 289 mobileHeight = image.data( 'mobile-height' ) 290 291 image.attr( 'src', '' ); 292 image.attr( 'data-src', src ); 293 294 if ( win.width() < window.themeopts.mobile_breakpoint ) { 295 296 if ( '' != mobileSrc ) { 297 tmpImage.onload = function() { 298 image.attr( 'src', mobileSrc ); 299 image.attr( 'width', mobileWidth ); 300 image.attr( 'height', mobileHeight ); 301 image.css( 'width', '' ); 302 }; 303 tmpImage.src = src; 304 image.show(); 305 } 306 } 307 else { 308 if ( 'undefined' !== typeof image.data('src') ) { 309 image.attr( 'src', image.data('src') ); 310 image.attr( 'width', width ); 311 image.attr( 'height', height ); 312 image.css( 'width', width ); 313 } 314 } 315 }); 316 }, 317 318 /** 319 * Toggles a collapsed navbar when the toggle button is 320 * clicked and the current framework is the bootstrap base. 321 * 322 * @since 1.7 323 * @param {Object} e 324 */ 325 navbarToggleClick: function( e ) { 326 var menuType = $('body').hasClass('fl-nav-mobile-offcanvas') ? 'flyout' : 'dropdown'; 327 328 if ( 'dropdown' === menuType ) { 329 var navBar = $(e.target).closest('.fl-page-nav'), 330 targetPanel = navBar.find('.fl-page-nav-collapse'); 331 332 targetPanel.toggleClass('collapse'); 333 targetPanel.toggleClass('in'); 334 335 } else if ( 'flyout' === menuType ) { 336 337 $( '.fl-page' ).toggleClass( 'fl-nav-offcanvas-active' ); 338 339 } 340 341 e.stopPropagation(); 342 }, 343 344 /** 345 * Closes Dropdown or Flyout Menu when clicked anywhere on the page. 346 * 347 * @since 1.7.9 348 * @param {Object} e 349 */ 350 closeMenu: function (e) { 351 var menuType = $( 'body' ).hasClass( 'fl-nav-mobile-offcanvas' ) ? 'flyout' : 'dropdown', 352 isDropdownMenuActive = $( '.fl-page-nav-collapse' ).hasClass( 'in' ), 353 isFlyoutMenuActive = $( '.fl-page' ).hasClass( 'fl-nav-offcanvas-active' ), 354 isMaxMegaMenu = $( e.target ).is( '.mega-toggle-animated-inner, .mega-menu-toggle-animated-block, .mega-toggle-animated-box, .mega-toggle-blocks-right' ), 355 pageNav; 356 357 if ( undefined === e || undefined === e.target || isMaxMegaMenu ) { 358 return; 359 } 360 361 if ( 'dropdown' === menuType && isDropdownMenuActive ) { 362 pageNav = $( '.navbar-collapse.in' ).closest( '.fl-page-nav' ); 363 pageNav.find( '.navbar-toggle' ).trigger( 'click' ); 364 } else if ( 'flyout' === menuType && isFlyoutMenuActive) { 365 $( '.fl-offcanvas-close' ).trigger( 'click' ); 366 } 367 }, 368 369 /** 370 * Initializes drop down nav logic. 371 * 372 * @since 1.0 373 * @access private 374 * @method _setupDropDowns 375 */ 376 _setupDropDowns: function() 377 { 378 $('ul.sub-menu').each(function(){ 379 $( this ).closest( 'li' ).find('a').first().attr( 'aria-haspopup', 'true' ); 380 }); 381 }, 382 383 /** 384 * Initializes drop down menu logic for top bar navs. 385 * 386 * @since 1.0 387 * @access private 388 * @method _enableTopNavDropDowns 389 */ 390 _enableTopNavDropDowns: function() 391 { 392 var nav = $('.fl-page-bar-nav'), 393 navItems = nav.find(' > li'), 394 subToggles = nav.find('> li').has('> ul.sub-menu').find('.fl-submenu-toggle-icon'); 395 396 if ( FLTheme._isMobile() ) { 397 if( false !== /iPhone|iPad/i.test( navigator.userAgent ) ) { 398 navItems.hover(FLTheme._navItemMouseover, FLTheme._navItemMouseout); 399 } 400 else { 401 navItems.hover(function(){}, FLTheme._navItemMouseout); 402 subToggles.on('click', FLTheme._navSubMenuToggleClick); 403 } 404 } 405 else { 406 navItems.hover(FLTheme._navItemMouseover, FLTheme._navItemMouseout); 407 } 408 }, 409 410 /** 411 * Fixes an ios quirk, if we have a dropdown menu and a user clicks 'back' 412 * the menu will stay open, ios does not reparse js when you click back. 413 * This method detects that back has been clicked by looking for event.persisted 414 * 415 * @since 1.6.2 416 * @method _navBackiosFix 417 */ 418 _navBackiosFix: function() { 419 ipad = (navigator.userAgent.match('iPhone|iPad') !== null && $('.menu-item-has-children').length > 0) ? true : false;
420 if( false !== ipad ) { 421 window.onpageshow = function(event) { 422 if (event.persisted) { 423 window.location.reload() 424 } 425 } 426 } 427 }, 428 429 /** 430 * Initializes builder smooth scrolling. 431 * 432 * @since 1.7.6 433 * @return void 434 */ 435 _initSmoothScroll: function() { 436 // Bail if builder doesn't exist. 437 if ('undefined' === typeof FLBuilderLayout) { 438 return; 439 } 440 441 // if scroll is disabled globally via filter do not scroll. 442 if ('undefined' !== typeof window.themeopts.smooth && 'disabled' === window.themeopts.smooth) { 443 return; 444 } 445 var targetId = location.hash; 446 targetId = targetId.replace( /(:|\!|\.|\[|\]|,|=|@|\/)/g, "\\$1" ); 447 if (targetId && $( targetId ).length) { 448 setTimeout(function() { 449 window.scrollTo(0, 0); 450 FLBuilderLayout._scrollToElement( $(targetId) ); 451 }, 1); 452 } 453 }, 454 455 /** 456 * Initializes drop down menu logic for the main nav for primary and fixed header. 457 * 458 * @since 1.0 459 * @access private 460 * @method _enablePageNavDropDowns 461 */ 462 _enablePageNavDropDowns: function() 463 { 464 var pageNav = $('.fl-page-header'); 465 466 pageNav.each( FLTheme._enablePageNavDropDown ); 467 }, 468 469 /** 470 * Callback logic for each main header nav dropdown 471 * 472 * @since 1.6 473 * @access private 474 * @method _enablePageNavDropDown 475 */ 476 _enablePageNavDropDown: function() 477 { 478 var pageNav = $(this), 479 nav = pageNav.find('.fl-page-nav .fl-page-nav-collapse'), 480 navItems = nav.find('ul li'), 481 subToggles = nav.find('li').has('> ul.sub-menu').find('> a'), 482 toggleIcon = nav.find('li').has('> ul.sub-menu').find('.fl-submenu-toggle-icon'), 483 subMenus = nav.find('> ul > li').has('ul.sub-menu'); 484 485 if( $( '.fl-page-nav .navbar-toggle' ).is( ':visible' ) ) { 486 navItems.off('mouseenter mouseleave'); 487 488 // Toggle submenu 489 if ( $( 'body' ).hasClass( 'fl-submenu-toggle' ) ) { 490 subMenus = nav.find('> ul li').has('ul.sub-menu'); 491 } 492 subMenus.find('> a').off().on('click', FLTheme._navItemClickMobile); 493 subMenus.find('.fl-submenu-toggle-icon').off().on('click', FLTheme._navItemClickMobile); 494 495 nav.find('.menu').on('click', '.menu-item > a[href*="#"]', FLTheme._toggleForMobile); 496 subToggles.off('click', FLTheme._navSubMenuToggleClick); 497 } 498 else { 499 nav.find('a').off('click', FLTheme._navItemClickMobile); 500 nav.find('a').off('click', FLTheme._toggleForMobile); 501 nav.find('.fl-submenu-toggle-icon').off('click', FLTheme._navItemClickMobile); 502 nav.removeClass('in').addClass('collapse'); 503 navItems.removeClass('fl-mobile-sub-menu-open'); 504 navItems.find('a').width(0).width('auto'); 505 506 if ( FLTheme._isMobile() ) { 507 navItems.hover(function(){}, FLTheme._navItemMouseout); 508 subToggles.on('click', FLTheme._navSubMenuToggleClick); 509 } 510 else { 511 navItems.keydown( function(e){ 512 if ( 9 === e.keyCode ) { 513 el = $(this) 514 focused = el.find(':focus') 515 if( focused.parent().is(':last-child') ) { 516 sub = focused.parent().find('ul.sub-menu').first() 517 mega = focused.parent().parent().parent().parent().parent().hasClass('mega-menu') 518 mega_last = focused.parent().parent().parent().is(':last-child' ) 519 520 if ( sub.length > 0 ) { 521 sub.trigger('mouseenter') 522 } else { 523 if ( ! mega || mega_last ) { 524 el.trigger('mouseleave') 525 } 526 } 527 } 528 parent = focused.closest('ul.sub-menu').parent() 529 if ( ! parent.hasClass('fl-sub-menu-open') ) { 530 focused.trigger('mouseenter') 531 } 532 } 533 } ); 534 navItems.hover(FLTheme._navItemMouseover, FLTheme._navItemMouseout); 535 } 536 } 537 }, 538 539 /** 540 * Callback for when an item in a nav is clicked on mobile. 541 * 542 * @since 1.0 543 * @access private 544 * @method _navItemClickMobile 545 * @param {Object} e The event object. 546 */ 547 _navItemClickMobile: function(e) 548 { 549 var nav = $(this).closest('.fl-page-nav-collapse'), 550 parent = $(this).closest('li'), 551 href = $(this).attr('href'), 552 subMenu = parent.find( 'ul.sub-menu' ), 553 toggle = $(e.target).hasClass('fl-submenu-toggle-icon'), 554 subChildren = null; 555 556 if( href && '#' !== href ) { 557 var targetId = href.split('#')[1]; 558 if ( $('body').find('#'+ targetId).length > 0 && parent.hasClass( 'fl-mobile-sub-menu-open' ) ) { 559 el = $(this).parent().closest('nav').find( '.navbar-toggle') 560 el.trigger('click'); 561 if ( 'undefined' !== typeof FLBuilderLayout && ( 'undefined' === typeof window.themeopts.smooth && 'disabled' !== window.themeopts.smooth ) ) { 562 setTimeout(function() { 563 window.scrollTo(0, 0); 564 FLBuilderLayout._scrollToElement( $('#'+ targetId) ); 565 }, 1); 566 } 567 } 568 } 569 570 if( ( '#' == href || toggle ) && parent.hasClass( 'fl-mobile-sub-menu-open' ) ) { 571 e.preventDefault(); 572 parent.removeClass('fl-mobile-sub-menu-open'); 573 subMenu.hide(); 574 } 575 else if(!parent.hasClass('fl-mobile-sub-menu-open')) { 576 577 e.preventDefault(); 578 parent.addClass('fl-mobile-sub-menu-open'); 579 580 if ( toggle && 0 === $('.fl-submenu-toggle').length ) { 581 subChildren = subMenu.find( 'li.menu-item-has-children' ); 582 subChildren.addClass('fl-mobile-sub-menu-open'); 583 } 584 585 subMenu.fadeIn(200); 586 } 587 588 if ( $( '.fl-nav-collapse-menu' ).length != 0 ) { 589 nav.find( 'li.fl-mobile-sub-menu-open' ) 590 .not( $(this).parents( '.fl-mobile-sub-menu-open' ) ) 591 .not( subChildren ) 592 .removeClass( 'fl-mobile-sub-menu-open' ) 593 .find( 'ul.sub-menu' ).hide(); 594 } 595 596 e.stopPropagation(); 597 }, 598 599 /** 600 * Setup and callback for nav item link that exists on a page. 601 * 602 * @since 1.5.3 603 * @access private 604 * @method _setupCurrentNavItem 605 * @param {Object|Null} e The event object. 606 */ 607 _setupCurrentNavItem: function(e) 608 { 609 var nav = $('.fl-page-nav .navbar-nav'), 610 targetId = typeof e !== 'undefined' ? $(e.target).prop('hash') : window.location.hash, 611 targetId = targetId.replace( /(:|\!|\.|\[|\]|,|=|@|\/)/g, "\\$1" ),
612 currentLink = targetId.length ? nav.find('a[href*=\\' + targetId + ']:not([href=\\#])') : null, 613 closeButton = nav.closest('.fl-page-nav').find('.fl-offcanvas-close'); 614 615 if ( currentLink != null && $('body').find(targetId).length > 0 ) { 616 $( '.current-menu-item' ).removeClass( 'current-menu-item' ); 617 currentLink.parent().addClass('current-menu-item'); 618 619 if ( closeButton ) { 620 closeButton.trigger( 'click' ); 621 } 622 } 623 }, 624 625 626 /** 627 * Callback for when the mouse leaves an item 628 * in a nav at desktop sizes. 629 * 630 * @since 1.0 631 * @access private 632 * @method _navItemMouseover 633 */ 634 _navItemMouseover: function() 635 { 636 if($(this).find('ul.sub-menu').length === 0) { 637 return; 638 } 639 640 var li = $(this), 641 parent = li.parent(), 642 subMenu = li.find('ul.sub-menu'), 643 subMenuWidth = subMenu.width(), 644 subMenuPos = 0, 645 winWidth = $(window).width(), 646 spacerPos = 0, 647 subMenuTopPos = 0; 648 649 if(li.closest('.fl-sub-menu-right').length !== 0) { 650 li.addClass('fl-sub-menu-right'); 651 } 652 else if($('body').hasClass('rtl')) { 653 654 subMenuPos = parent.is('ul.sub-menu') ? 655 parent.offset().left - subMenuWidth: 656 li.offset().left - subMenuWidth; 657 658 if(subMenuPos <= 0) { 659 li.addClass('fl-sub-menu-right'); 660 } 661 } 662 else { 663 664 subMenuPos = parent.is('ul.sub-menu') ? 665 parent.offset().left + (subMenuWidth * 2) : 666 li.offset().left + subMenuWidth; 667 668 if(subMenuPos > winWidth) { 669 li.addClass('fl-sub-menu-right'); 670 } 671 } 672 673 li.addClass('fl-sub-menu-open'); 674 675 if ( ! li.hasClass('hide-heading') ) { 676 subMenu.hide(); 677 subMenu.stop().fadeIn(200); 678 } 679 680 FLTheme._hideNavSearch(); 681 682 // Mega menu hover fix 683 if ( li.closest( '.fl-page-nav-collapse' ).length !== 0 && li.hasClass( 'mega-menu' ) ) { 684 685 if ( li.find( '.mega-menu-spacer' ).length > 0 ) { 686 return; 687 } 688 689 subMenu.first().before( '<div class="mega-menu-spacer"></div>' ); 690 spacerPos = li.find( '.mega-menu-spacer' ).offset().top; 691 subMenuTopPos = subMenu.first().offset().top; 692 li.find( '.mega-menu-spacer' ).css('padding-top', Math.floor( parseInt(subMenuTopPos - spacerPos) ) + 'px' ); 693 } 694 }, 695 696 /** 697 * Callback for when the mouse leaves an item 698 * in a nav at desktop sizes. 699 * 700 * @since 1.0 701 * @access private 702 * @method _navItemMouseout 703 */ 704 _navItemMouseout: function() 705 { 706 var li = $(this), 707 subMenu = li.find('ul.sub-menu'); 708 709 710 if ( ! li.hasClass('hide-heading') ) { 711 subMenu.stop().fadeOut({ 712 duration: 200, 713 done: FLTheme._navItemMouseoutComplete 714 }); 715 } 716 else { 717 FLTheme._navItemMouseoutComplete(); 718 } 719 }, 720 721 /** 722 * Callback for when the mouse finishes leaving an item 723 * in a nav at desktop sizes. 724 * 725 * @since 1.0 726 * @access private 727 * @method _navItemMouseoutComplete 728 */ 729 _navItemMouseoutComplete: function() 730 { 731 var li = $(this).parent(); 732 733 li.removeClass('fl-sub-menu-open'); 734 li.removeClass('fl-sub-menu-right'); 735 736 if ( li.find( '.mega-menu-spacer' ).length > 0 ) { 737 li.find( '.mega-menu-spacer' ).remove(); 738 } 739 740 $(this).show(); 741 }, 742 743 /** 744 * Callback for when a submenu toggle is clicked on mobile. 745 * 746 * @since 1.5.1 747 * @access private 748 * @method _navSubToggleClick 749 * @param {Object} e The event object. 750 */ 751 _navSubMenuToggleClick: function( e ) 752 { 753 var li = $( this ).closest( 'li' ).eq( 0 ); 754 755 if ( ! li.hasClass( 'fl-sub-menu-open' ) ) { 756 FLTheme._navItemMouseover.apply( li[0] ); 757 758 e.preventDefault(); 759 } 760 }, 761 762 /** 763 * Logic for the menu item when clicked on mobile. 764 * 765 * @since 1.5.3 766 * @return void 767 */ 768 _toggleForMobile: function( e ){ 769 var nav = $('.fl-page-nav .fl-page-nav-collapse'), 770 href = $(this).attr('href'), 771 hasSubmenu = $(this).closest('li').hasClass( 'menu-item-has-children' ); 772 773 if ( href !== '#' ) { 774 var targetId = href.split('#')[1]; 775 776 if ( $('body').find('#'+ targetId).length > 0 && !hasSubmenu ) { 777 /** 778 * Make sure bootstrap collapse is available before using it. 779 */ 780 if ( ! $.isFunction(nav.collapse) ) { 781 el = $(this).parent().closest('nav').find( '.navbar-toggle') 782 el.trigger('click') 783 } else { 784 nav.collapse('hide'); 785 } 786 } 787 } 788 }, 789 790 /** 791 * Shows or hides the nav search form. 792 * 793 * @since 1.0 794 * @access private 795 * @method _toggleNavSearch 796 */ 797 _toggleNavSearch: function(e) 798 { 799 var form = $('.fl-page-nav-search form'); 800 801 e.preventDefault(); 802 803 if(form.is(':visible')) { 804 form.stop().fadeOut(200); 805 } 806 else { 807 form.stop().fadeIn(200); 808 $('body').on('click.fl-page-nav-search', FLTheme._hideNavSearch); 809 $('.fl-page-nav-search .fl-search-input').focus(); 810 } 811 }, 812 813 /** 814 * Hides the nav search form. 815 * 816 * @since 1.0 817 * @access private 818 * @method _hideNavSearch 819 * @param {Object} e (Optional) An event object. 820 */ 821 _hideNavSearch: function(e) 822 { 823 var form = $('.fl-page-nav-search form'); 824 825 if(e !== undefined) { 826 if($(e.target).closest('.fl-page-nav-search').length > 0) { 827 return; 828 } 829 } 830 831 form.stop().fadeOut(200); 832 833 $('body').off('click.fl-page-nav-search'); 834 }, 835 836 /** 837 * Nav Vertical 838 * 839 * @since 1.5 840 * @access private 841 * @method _navVertical 842 */ 843 _navVertical: function() 844 { 845 var win = $(window); 846 847 848 if(win.width() >= window.themeopts.medium_breakpoint && $('.fl-page-header-primary').hasClass('fl-page-nav-toggle-visible-always')){ 849 $('body').toggleClass('fl-nav-vertical'); 850 851 if( $('body').hasClass('fl-nav-vertical-left') ) { 852 $('body').toggleClass('fl-nav-vertical-left'); 853 } 854 855 if( $('body').hasClass('fl-nav-vertical-right') ) { 856 $('body').toggleClass('fl-nav-vertical-right'); 857 } 858 } 859 }, 860 861 /** 862 * Right position fix for right navigation on boxed layout 863 * 864 * @since 1.5 865 * @access private 866 * @method _updateVerticalRightPos 867 */ 868 _updateVerticalRightPos: function() 869 { 870 var win = $(window).width(), 871 flpage = $('.fl-page').width(), 872 vericalRightPos = ( (win - flpage) / 2 ); 873 874 $('.fl-page-header-vertical').css('right', vericalRightPos); 875 }, 876 877 /** 878 * Nav Left 879 * 880 * @since 1.5 881 * @access private 882 * @method _navLeft 883 */ 884 _navLeft: function() 885 { 886 var win = $(window); 887 888 if(win.width() < window.themeopts.medium_breakpoint || $('.fl-page-header-primary').hasClass('fl-page-nav-toggle-visible-always')) { 889 $('.fl-page-header-primary .fl-page-logo-wrap').insertBefore('.fl-page-header-primary .fl-page-nav-col'); 890 } 891 if(win.width() >= window.themeopts.medium_breakpoint && !$('.fl-page-header-primary').hasClass('fl-page-nav-toggle-visible-always')) { 892 $('.fl-page-header-primary .fl-page-nav-col').insertBefore('.fl-page-header-primary .fl-page-logo-wrap'); 893 } 894 895 if($('.fl-page-header-fixed').length != 0 && ! $('.fl-page-header-fixed').hasClass('fl-page-nav-toggle-visible-always') ) { 896 $('.fl-page-header-fixed .fl-page-fixed-nav-wrap').insertBefore('.fl-page-header-fixed .fl-page-logo-wrap'); 897 } 898 }, 899 900 /** 901 * Initialize header shrinking. 902 * 903 * @since 1.5.2 904 * @access private 905 * @method _shrinkHeaderInit 906 */ 907 _shrinkHeaderInit: function() 908 { 909 var distanceY = $(window).scrollTop(), 910 shrinkOn = 250, 911 header = $( '.fl-page-header' ); 912 913 $( 'body' ).addClass( 'fl-shrink-header-enabled' ); 914 915 if ('scrollRestoration' in history) { 916 history.scrollRestoration = 'manual'; 917 } 918 919 $('.fl-page-header-logo').imagesLoaded(function(){ 920 var logo = $( '.fl-logo-img' ), 921 logoForHeight = $( '.fl-page-header-logo:visible .fl-logo-img' ).first(); 922 923 if ( ! logoForHeight.length ) { 924 logoForHeight = logo.first(); 925 } 926 927 var logoHeight = logoForHeight.length ? logoForHeight.height() : 0; 928 929 if ( 'undefined' !== typeof logoForHeight.data('origHeight') ) { 930 logoHeight = parseInt( logoForHeight.data('origHeight') ); 931 } 932 if ( ! logoHeight && logo.length ) { 933 logoHeight = parseInt( logo.first().data('origHeight') ) || 46; 934 } 935 936 logo.css( 'max-height', logoHeight ); 937 938 setTimeout( function() { 939 $('.fl-page-header').addClass( 'fl-shrink-header-transition' ); 940 941 // Shrink on page load 942 if ( distanceY > shrinkOn ) { 943 header.addClass( 'fl-shrink-header' ); 944 } 945 else { 946 header.removeClass( 'fl-shrink-header' ); 947 } 948 }, 100 ); 949 }); 950 }, 951 952 /** 953 * Enable or disable header shrinking. 954 * 955 * @since 1.5 956 * @access private 957 * @method _shrinkHeaderEnable 958 */ 959 _shrinkHeaderEnable: function() 960 { 961 var win = $( window ); 962 963 if ( win.width() >= window.themeopts.medium_breakpoint ) { 964 965 var header = $('.fl-page-header'), 966 headerHeight = header.outerHeight(), 967 topbar = $('.fl-page-bar'), 968 topbarHeight = 0, 969 totalHeaderHeight = 0; 970 971 if( topbar.length != 0 ) { 972 topbarHeight += topbar.outerHeight(); 973 totalHeaderHeight = topbarHeight + headerHeight; 974 975 if ( $( 'body.admin-bar' ).length != 0 ) { 976 topbarHeight += 32; 977 } 978 } 979 else { 980 totalHeaderHeight = headerHeight; 981 } 982 983 if ( topbarHeight > 0 ) {
984 header.css( 'top' , topbarHeight ); 985 } else { 986 header.css( 'top' , '' ); 987 } 988 989 // Fix: Themer parts layout inserted before header. 990 if ( header.prevAll( '.fl-builder-content' ).length > 0 ) { 991 FLTheme._initThemerLayoutFix(); 992 993 totalHeaderHeight = topbar.outerHeight(); 994 } 995 996 if ( $('.fl-header-padding-top-custom').length === 0 ) { 997 $( '.fl-page' ).css( 'padding-top', totalHeaderHeight ); 998 } else { 999 $( '.fl-page' ).css( 'padding-top', '' ); 1000 } 1001 1002 $( win ).on( 'scroll.fl-shrink-header', FLTheme._shrinkHeader ); 1003 } 1004 else { 1005 $('.fl-page-header').css('top', 0); 1006 $( '.fl-page' ).css( 'padding-top', 0 ); 1007 $( win ).off( 'scroll.fl-shrink-header' ); 1008 } 1009 }, 1010 1011 /** 1012 * Shrink the header. 1013 * 1014 * @since 1.5.1 1015 * @access private 1016 * @method _shrinkHeader 1017 */ 1018 _shrinkHeader: function() 1019 { 1020 var distanceY = $( this ).scrollTop(), 1021 shrinkOn = 250, 1022 header = $( '.fl-page-header' ), 1023 logo = null; 1024 1025 $('.fl-page-header-logo').imagesLoaded(function(){ 1026 logo = $( '.fl-logo-img' ); 1027 1028 var logoForHeight = $( '.fl-page-header-logo:visible .fl-logo-img' ).first(); 1029 1030 if ( ! logoForHeight.length ) { 1031 logoForHeight = logo.first(); 1032 } 1033 1034 var origHeight = logoForHeight.length ? logoForHeight.height() : ( logo.first().data('origHeight') || 46 ); 1035 1036 if ( 'undefined' === typeof logo.data('origHeight') ) { 1037 logo.data( 'origHeight', origHeight ); 1038 1039 if ( logoForHeight.length && ! logoForHeight.is( logo.first() ) ) { 1040 logoForHeight.data( 'origHeight', origHeight ); 1041 } 1042 } 1043 1044 if ( distanceY > shrinkOn ) { 1045 header.addClass( 'fl-shrink-header' ); 1046 } 1047 else { 1048 header.removeClass( 'fl-shrink-header' ); 1049 } 1050 1051 if ( 'undefined' !== typeof header.data( 'original-top' ) ) { 1052 FLTheme._fixThemerLayoutOnScroll(); 1053 } 1054 }); 1055 }, 1056 1057 /** 1058 * Fixed Header (Fixed) 1059 * 1060 * @since 1.5 1061 * @access private 1062 * @method _fixedHeader 1063 */ 1064 _fixedHeader: function() 1065 { 1066 var win = $(window), 1067 header = $('.fl-page-header'), 1068 headerHeight = 0, 1069 totalHeaderHeight = 0, 1070 bar = $('.fl-page-bar'), 1071 barHeight = 0; 1072 1073 if(win.width() >= window.themeopts.medium_breakpoint) { 1074 1075 headerHeight = header.outerHeight(); 1076 1077 if( bar.length != 0 ) { 1078 1079 barHeight = bar.outerHeight(); 1080 totalHeaderHeight = barHeight + headerHeight; 1081 1082 if($('body.admin-bar').length != 0) { 1083 barHeight += 32; 1084 } 1085 1086 if($('html.fl-builder-edit').length != 0) { 1087 var topbarHeight = topbarHeight+11; 1088 } 1089 1090 } 1091 else { 1092 totalHeaderHeight = headerHeight; 1093 } 1094 1095 if ( barHeight > 0 ) { 1096 header.css( 'top' , barHeight ); 1097 } else { 1098 header.css( 'top' , '' ); 1099 } 1100 1101 // Fix: Themer parts layout. 1102 if ( header.prevAll( '.fl-builder-content' ).length > 0 ) { 1103 FLTheme._initThemerLayoutFix(); 1104 totalHeaderHeight = bar.outerHeight(); 1105 1106 $( win ).on( 'scroll.fl-fixed-header', FLTheme._fixThemerLayoutOnScroll ); 1107 } 1108 1109 if($('body.fl-scroll-header').length === 0 && $('.fl-header-padding-top-custom').length === 0 ) { 1110 $('.fl-page').css('padding-top', totalHeaderHeight); 1111 } else { 1112 $( '.fl-page' ).css( 'padding-top', '' ); 1113 } 1114 1115 $( win ).trigger( 'scroll' ); 1116 } 1117 else { 1118 $('.fl-page-header').css('top', 0); 1119 $('.fl-page').css('padding-top', 0); 1120 $( win ).off( 'scroll.fl-fixed-header' ); 1121 } 1122 }, 1123 1124 /** 1125 * Fixed Header (Fade In) 1126 * 1127 * Enables the fixed header if the window is wide enough. 1128 * 1129 * @since 1.0 1130 * @access private 1131 * @method _enableFixedHeader 1132 */ 1133 _enableFixedHeader: function() 1134 { 1135 var win = $(window); 1136 1137 if(win.width() < window.themeopts.medium_breakpoint) { 1138 win.off('scroll.fl-page-header-fixed'); 1139 $('.fl-page-header-fixed').hide(); 1140 } 1141 else { 1142 win.on('scroll.fl-page-header-fixed', FLTheme._toggleFixedHeader); 1143 } 1144 }, 1145 1146 /** 1147 * Fix the Themer parts layout that are hooks into `fl_page_open`. 1148 * 1149 * @since 1.7 1150 * @access private 1151 * @method _fixThemerLayout 1152 */ 1153 _initThemerLayoutFix: function() { 1154 var header = $('.fl-page-header'),
1155 themerLayouts = header.prevAll( '.fl-builder-content' ), 1156 themerlayoutHeight = 0; 1157 1158 if ( ! themerLayouts.length ) { 1159 return; 1160 } 1161 1162 header.css('position', 'initial'); 1163 1164 $.each( themerLayouts, function() { 1165 themerlayoutHeight += $( this ).outerHeight(); 1166 }); 1167 1168 header.data( 'original-top', themerlayoutHeight ); 1169 }, 1170 1171 /** 1172 * Fix the Themer parts layout on scroll. 1173 * 1174 * @since 1.7 1175 * @access private 1176 * @method _fixThemerLayout 1177 */ 1178 _fixThemerLayoutOnScroll: function() { 1179 var distanceY = $( window ).scrollTop(), 1180 header = $( '.fl-page-header' ), 1181 headerTop = header.data( 'original-top' ); 1182 1183 if ( 'undefined' === typeof headerTop ) { 1184 return; 1185 } 1186 1187 if ( distanceY >= headerTop ) { 1188 header.css( 'position', 'fixed' ); 1189 } 1190 else { 1191 header.css( 'position', 'initial' ); 1192 } 1193 1194 // Fix animations. 1195 if ( 'undefined' != typeof Waypoint ) { 1196 Waypoint.refreshAll(); 1197 } 1198 }, 1199 1200 /** 1201 * Shows or hides the fixed header based on the 1202 * window's scroll position. 1203 * 1204 * @since 1.0 1205 * @access private 1206 * @method _toggleFixedHeader 1207 */ 1208 _toggleFixedHeader: function() 1209 { 1210 var win = $(window), 1211 fixed = $('.fl-page-header-fixed'), 1212 fixedVisible = fixed.is(':visible'), 1213 header = $('.fl-page-header-primary'), 1214 headerHidden = false; 1215 1216 if ( 0 === header.length ) { 1217 headerHidden = win.scrollTop() > 200; 1218 } 1219 else { 1220 headerHidden = win.scrollTop() > header.height() + header.offset().top; 1221 } 1222 1223 if(headerHidden && !fixedVisible) { 1224 fixed.stop().fadeIn(200); 1225 } 1226 else if(!headerHidden && fixedVisible) { 1227 fixed.stop().hide(); 1228 } 1229 }, 1230 1231 /** 1232 * Adds logo as nav item for "centered inline logo" header layout. 1233 * 1234 * @since 1.5 1235 * @access private 1236 * @method _centeredInlineLogo 1237 */ 1238 _centeredInlineLogo: function() 1239 { 1240 var win = $(window), 1241 $logo = $( '.fl-page-nav-centered-inline-logo .fl-page-header-logo' ).eq( 0 ), 1242 $inline_logo = $( '.fl-logo-centered-inline .fl-page-header-logo' ), 1243 $nav = $( '.fl-page-nav-centered-inline-logo .fl-page-nav .navbar-nav' ), 1244 nav_li_length = $nav.children('li').length, 1245 logo_li_location = Math.round( nav_li_length / 2 ) - 1, 1246 $header_row = $( '.fl-page-nav-centered-inline-logo .fl-page-header-row' ); 1247 1248 if(win.width() >= window.themeopts.medium_breakpoint && $inline_logo.length < 1 && !$('.fl-page-header-primary').hasClass('fl-page-nav-toggle-visible-always')) { 1249 1250 if( $logo.hasClass( 'fl-inline-logo-left' ) && nav_li_length % 2 != 0 ) { 1251 $nav.children( 'li:nth( '+logo_li_location+' )' ).before( '<li class="fl-logo-centered-inline"></li>' ); 1252 } else { 1253 $nav.children( 'li:nth( '+logo_li_location+' )' ).after( '<li class="fl-logo-centered-inline"></li>' ); 1254 } 1255 1256 $nav.children( '.fl-logo-centered-inline' ).append( $logo ); 1257 } 1258 1259 if(win.width() < window.themeopts.medium_breakpoint) { 1260 $( '.fl-logo-centered-inline' ).remove(); 1261 1262 if ( $header_row.children( '.fl-page-header-logo').length < 1 ) { 1263 $header_row.prepend( $inline_logo ); 1264 } 1265 } 1266 }, 1267 1268 /** 1269 * Hide Header Until Scroll 1270 * 1271 * @since 1.5 1272 * @access private 1273 * @method _scrollHeader 1274 */ 1275 _scrollHeader: function() 1276 { 1277 var win = $(window), 1278 header = null, 1279 distance = $('.fl-page-header-primary').data('fl-distance'), 1280 headerHeight = 0; 1281 1282 if($('.fl-page-bar').length != 0 ) { 1283 header = $('.fl-page-header-primary, .fl-page-bar'); 1284 } 1285 else { 1286 header = $('.fl-page-header-primary'); 1287 } 1288 1289 if(win.width() >= window.themeopts.medium_breakpoint) { 1290 win.on('scroll.fl-show-header-on-scroll', function () { 1291 if ($(this).scrollTop() > distance) { 1292 header.addClass('fl-show'); 1293 } 1294 else { 1295 header.removeClass('fl-show'); 1296 1297 // Offcanvas nav layout fix. 1298 if ( $('.fl-responsive-nav-enabled').length ) { 1299 headerHeight = $('.fl-page-header-primary').height() * 2; 1300 1301 if ( $('.fl-page-bar').length != 0 ) { 1302 headerHeight += $('.fl-page-bar').height(); 1303 } 1304 1305 if ( 'undefined' !== typeof $( '.fl-nav-offcanvas-collapse' ).css('top') ) { 1306 headerHeight += parseInt( $( '.fl-nav-offcanvas-collapse' ).css('top') ); 1307 } 1308 } 1309 1310 if ( $( '.fl-nav-offcanvas-active' ).length && headerHeight > 0 ) { 1311 $( '.fl-nav-offcanvas-collapse' ).css({ 1312 'transform' : 'translateY(' + headerHeight + 'px)', 1313 '-ms-transform' : 'translateY(' + headerHeight + 'px)', 1314 '-webkit-transform' : 'translateY(' + headerHeight + 'px)' 1315 }); 1316 } 1317 } 1318 }); 1319 } 1320 else { 1321 win.off('scroll.fl-show-header-on-scroll'); 1322 $( '.fl-nav-offcanvas-collapse' ).css('transform', ''); 1323 } 1324 }, 1325 1326 /** 1327 * Mega Menu 1328 * 1329 * @see _isResponsiveNavEnabled 1330 * @since 1.5 1331 * @access private 1332 * @method _megaMenu 1333 */ 1334 _megaMenu: function() 1335 { 1336 var win = $(window), 1337 pageHeaderMenu = $('.fl-page-header'), 1338 menuContainer = pageHeaderMenu.find('.fl-page-header-container'), 1339 menuWidthLimit = menuContainer.outerWidth(), 1340 megaItem = null, 1341 megaItems = null, 1342 megaContentWidth = 0; 1343 1344 pageHeaderMenu.find( 'li.mega-menu, li.mega-menu-disabled' ).each(function(){ 1345 megaItem = $(this); 1346 megaContentWidth = megaItem.find('> ul.sub-menu').outerWidth(); 1347 1348 if ( typeof megaItem.data('megamenu-width') !== 'undefined' ) { 1349 megaContentWidth = megaItem.data('megamenu-width'); 1350 } 1351 1352 if( ( megaItem.hasClass('mega-menu') && menuWidthLimit < megaContentWidth ) || FLTheme._isResponsiveNavEnabled() ) { 1353 megaItem.data('megamenu-width', megaContentWidth); 1354 1355 // Fixed width issue on window resize 1356 if ( FLTheme._isResponsiveNavEnabled() ) { 1357 megaItem.find('> ul.sub-menu').css('display', 'block'); 1358 } 1359 1360 megaItem.removeClass('mega-menu'); 1361 if (!megaItem.hasClass('mega-menu-disabled')) { 1362 megaItem.addClass('mega-menu-disabled'); 1363 } 1364 } 1365 else if ( megaItem.hasClass('mega-menu-disabled') && menuWidthLimit >= megaContentWidth ) { 1366 // Reset sub-menu display style 1367 megaItem.find('> ul.sub-menu').css('display', ''); 1368 1369 megaItem.removeClass('mega-menu-disabled'); 1370 if (!megaItem.hasClass('mega-menu')) { 1371 megaItem.addClass('mega-menu'); 1372 } 1373 megaItem.addClass( 'mega-menu-items-' + megaItem.children( 'ul' ).children( 'li' ).length ); 1374 } 1375 }); 1376 1377 1378 }, 1379 1380 /** 1381 * Mega Menu - Fixed Header 1382 * 1383 * @since 1.5 1384 * @access private 1385 * @method _megaMenuOnScroll 1386 */ 1387 _megaMenuOnScroll: function() 1388 { 1389 var win = $(window), 1390 pageHeaderFixed = $('.fl-page-header-fixed'), 1391 menuContainer = pageHeaderFixed.find('.fl-page-header-container'), 1392 fixedVisible = pageHeaderFixed.is(':visible'), 1393 megaItem = null, 1394 megaMenuContent = null; 1395 1396 if ( fixedVisible ) { 1397 pageHeaderFixed.find( 'li.mega-menu' ).each(function(){ 1398 megaItem = $(this); 1399 megaMenuContent = megaItem.find('> ul.sub-menu'); 1400 1401 // Disable mega menu if it's off screen 1402 if(menuContainer.outerWidth() < megaMenuContent.outerWidth()) { 1403 megaItem.removeClass('mega-menu'); 1404 if (!megaItem.hasClass('mega-menu-disabled')) { 1405 megaItem.addClass('mega-menu-disabled'); 1406 } 1407 } 1408 else { 1409 megaItem.removeClass('mega-menu-disabled'); 1410 if (!megaItem.hasClass('mega-menu')) { 1411 megaItem.addClass('mega-menu'); 1412 } 1413 1414 megaItem.addClass( 'mega-menu-items-' + megaItem.children( 'ul' ).children( 'li' ).length ); 1415 } 1416 }); 1417 1418 win.off('scroll.fl-mega-menu-on-scroll'); 1419 win.off('resize.fl-mega-menu-on-scroll'); 1420 } 1421 }, 1422 1423 /** 1424 * Fixed headers not be fixed when the builder is active 1425 * 1426 * @since 1.5.2 1427 * @access private 1428 * @method _fixedHeadersWhenBuilderActive 1429 */ 1430 _fixedHeadersWhenBuilderActive: function() 1431 { 1432 if($('body.fl-shrink').length != 0) { 1433 $('body').removeClass('fl-shrink'); 1434 } 1435 1436 if($('body.fl-fixed-header').length != 0) { 1437 $('body').removeClass('fl-fixed-header'); 1438 } 1439 1440 if($('body.fl-scroll-header').length != 0) { 1441 $('body').removeClass('fl-scroll-header'); 1442 } 1443 }, 1444 1445 /** 1446 * Responsive Nav Layout 1447 * 1448 * @since 1.7 1449 * @access private 1450 * @method _setupMobileNavLayout 1451 */ 1452 _setupMobileNavLayout: function() 1453 { 1454 var win = $( window ), 1455 button = $( 'button.navbar-toggle' ), 1456 header = $( '.fl-page-header:not(.fl-page-header-fixed)' ), 1457 navBar = header.find( '.fl-page-nav-collapse' ), 1458 pageWrap = $( '.fl-page' ), 1459 navBarTop = 0, 1460 navHeight = win.height(), 1461 pushOpacity = $( 'body').hasClass( 'fl-offcanvas-push-opacity-left' ) || $( 'body').hasClass( 'fl-offcanvas-push-opacity-right' ), 1462 logoPos = header.find( '.fl-page-header-logo' ).offset(); 1463 1464 if ( FLTheme._isResponsiveNavEnabled() && button.is( ':visible' ) ) { 1465 $( 'body' ).addClass( 'fl-responsive-nav-enabled' ); 1466 1467 button.attr( 'data-toggle', 'offcanvas'); 1468 navBar.addClass( 'fl-nav-offcanvas-collapse'); 1469 1470 if ( 0 === navBar.find( '.fl-button-close' ).length ) { 1471 navBar.prepend( '<div class="fl-button-close"><button class="fl-offcanvas-close" aria-label="Close Menu"><i class="fas fa-times"></i></button></div>' ); 1472 } 1473 1474 if ( pushOpacity && 0 === $( '.fl-offcanvas-opacity' ).length ) { 1475 pageWrap.append( '<div class="fl-offcanvas-opacity"></div>' ); 1476 } 1477 1478 if ( pageWrap.height() > win.height() ) { 1479 navHeight = $( document ).height(); 1480 1481 if ( $( 'body.fl-shrink' ).length != 0 ) { 1482 navHeight = navHeight - header.height(); 1483 } 1484 } 1485 1486 if ( $( 'body.admin-bar' ).length != 0 ) { 1487 navBarTop = $( '#wpadminbar' ).height(); 1488 navHeight = navHeight - navBarTop; 1489 } 1490 1491 if ( $( '.fl-page-bar' ).length != 0 && ! $( '.fl-page-header' ).hasClass( 'fl-page-nav-toggle-button' ) ) {
1492 navBarTop = navBarTop + ($( '.fl-page-bar' ).height() + 1); 1493 } 1494 1495 if ( $('.fl-scroll-header').length && win.width() >= window.themeopts.medium_breakpoint ) { 1496 navBar.css('top', pageWrap.offset().top - navBarTop + 'px' ); 1497 } 1498 else { 1499 navBar.css('top', ''); 1500 } 1501 1502 } 1503 else { 1504 button.attr( 'data-toggle', 'collapse'); 1505 navBar.removeClass( 'fl-nav-offcanvas-collapse'); 1506 navBar.find( '.fl-button-close' ).remove(); 1507 navBar.css( 'height', '' ); 1508 navBar.css( 'top', '' ); 1509 pageWrap.removeClass( 'fl-nav-offcanvas-active' ); 1510 $( 'body' ).find( '.fl-offcanvas-opacity' ).remove(); 1511 $( 'body' ).removeClass( 'fl-responsive-nav-enabled' ); 1512 } 1513 }, 1514 1515 /** 1516 * Toggle the Responsive Nav Layout 1517 * 1518 * @since 1.7 1519 * @access private 1520 * @method _toggleMobileNavLayout 1521 */ 1522 _toggleMobileNavLayout: function() 1523 { 1524 1525 $( '.fl-page-nav' ).on( 'click', '.fl-offcanvas-close', function(e){ 1526 $( '.fl-page' ).toggleClass( 'fl-nav-offcanvas-active' ); 1527 e.stopPropagation(); 1528 }); 1529 1530 }, 1531 1532 /** 1533 * Apply footer height as margin-bottom value for fl-page class 1534 * 1535 * @since 1.5 1536 * @access private 1537 * @method _footerEffect 1538 */ 1539 _footerEffect: function() 1540 { 1541 if ( $( window ).width() >= window.themeopts.mobile_breakpoint ) { 1542 $( '.fl-page' ).css( 'margin-bottom', $( '.fl-page-footer-wrap' ).height() ); 1543 } 1544 else { 1545 $( '.fl-page' ).css( 'margin-bottom', 0 ); 1546 } 1547 }, 1548 1549 /** 1550 * Go to Top 1551 * 1552 * @since 1.5 1553 * @access private 1554 * @method _toTop 1555 */ 1556 _toTop: function() 1557 { 1558 var buttons = $('#fl-to-top'); 1559 1560 buttons.each(function(){ 1561 $(this).click(function(){ 1562 $('html,body').animate({ scrollTop: 0 }, 'linear'); 1563 return false; 1564 }); 1565 }); 1566 1567 $(window).scroll(function(){ 1568 if( $(this).scrollTop() > window.themeopts.scrollTopPosition ) { 1569 buttons.fadeIn(); 1570 } else { 1571 buttons.fadeOut(); 1572 } 1573 }); 1574 }, 1575 1576 /** 1577 * Initializes the lightbox. 1578 * 1579 * @since 1.0 1580 * @access private 1581 * @method _enableLightbox 1582 */ 1583 _enableLightbox: function() 1584 { 1585 var body = $('body'); 1586 1587 if ( 'disabled' === window.themeopts.lightbox ) { 1588 return; 1589 } 1590 1591 // Only works on NON bb pages/posts 1592 if( !body.hasClass('fl-builder') && !body.hasClass('woocommerce')) { 1593 1594 $('.fl-content a').filter(function() { 1595 return /\.(png|jpg|jpeg|gif|webp)(\?.*)?$/i.test(this.href); 1596 }).magnificPopup({ 1597 closeBtnInside: false, 1598 type: 'image', 1599 gallery: { 1600 enabled: true 1601 } 1602 }); 1603 } 1604 1605 if( ( body.hasClass('fl-builder') || body.hasClass( 'fl-theme-builder-singular' ) ) && !body.hasClass('woocommerce') ) { 1606 $('.fl-rich-text a, .fl-module-fl-post-content a').filter(function() { 1607 return /\.(png|jpg|jpeg|gif|webp)(\?.*)?$/i.test(this.href); 1608 }).magnificPopup({ 1609 closeBtnInside: false, 1610 type: 'image', 1611 gallery: { 1612 enabled: true 1613 } 1614 }); 1615 } 1616 }, 1617 1618 /** 1619 * Initializes the fitVids 1620 * 1621 * @since 1.5.2 1622 * @access private 1623 * @method _enableFitVids 1624 */ 1625 _enableFitVids: function() 1626 { 1627 $('.fl-post-content').fitVids( { 1628 ignore: '.wp-block-embed *' 1629 } ); 1630 }, 1631 1632 /** 1633 * Check to see if responsive nav is enabled for the current window width 1634 * 1635 * @since 1.6.2 1636 * @access private 1637 * @method _isResponsiveNavEnabled 1638 */ 1639 _isResponsiveNavEnabled: function() 1640 { 1641 var win = $(window); 1642 enabled = false; 1643 1644 if ( ( $( '.fl-page-nav-toggle-visible-always' ).length > 0 ) 1645 || ( $( '.fl-page-nav-toggle-visible-medium-mobile' ).length > 0 && win.width() < window.themeopts.medium_breakpoint ) 1646 || ( $( '.fl-page-nav-toggle-visible-mobile' ).length > 0 && win.width() < window.themeopts.mobile_breakpoint ) 1647 ) { 1648 enabled = true; 1649 } 1650 1651 return enabled; 1652 } 1653 }; 1654 1655 $(function(){ 1656 FLTheme.init(); 1657 }); 1658 1659 // Mobile Logo 1660 if ( ! ( $( 'html.fl-builder-edit' ).length !== 0 ) ) { 1661 FLTheme._initMobileHeaderLogo(); 1662 } 1663 FLTheme._initRetinaImages(); 1664 1665})(jQuery);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.