2016-10-30 01:02:14 +02:00
/ *
2021-10-02 11:28:46 +02:00
GreedyNav . js - http : //lukejacksonn.com/actuate
2017-09-28 23:42:38 +02:00
Licensed under the MIT license - http : //opensource.org/licenses/MIT
Copyright ( c ) 2015 Luke Jackson
2016-10-30 01:02:14 +02:00
* /
2023-09-30 18:45:32 +02:00
/* hacks-guide change: add language selector, remove logo */
2021-10-02 11:28:46 +02:00
$ ( function ( ) {
2017-09-28 23:42:38 +02:00
2021-10-02 11:28:46 +02:00
var $btn = $ ( "nav.greedy-nav .greedy-nav__toggle" ) ;
var $btn2 = $ ( "nav.greedy-nav .greedy-nav__toggle_lang" ) ;
var $vlinks = $ ( "nav.greedy-nav .visible-links" ) ;
var $hlinks = $ ( "nav.greedy-nav .hidden-links.links-menu" ) ;
var $hlinks2 = $ ( "nav.greedy-nav .hidden-links.lang-menu" ) ;
var $nav = $ ( "nav.greedy-nav" ) ;
// var $logo = $('nav.greedy-nav .site-logo');
var $logoImg = $ ( 'nav.greedy-nav .site-logo img' ) ;
// var $title = $("nav.greedy-nav .site-title");
var $search = $ ( 'nav.greedy-nav button.search__toggle' ) ;
2017-09-28 23:42:38 +02:00
2021-10-02 11:28:46 +02:00
var numOfItems , totalSpace , closingTime , breakWidths ;
2017-09-28 23:42:38 +02:00
2021-10-02 11:28:46 +02:00
// This function measures both hidden and visible links and sets the navbar breakpoints
// This is called the first time the script runs and everytime the "check()" function detects a change of window width that reached a different CSS width breakpoint, which affects the size of navbar Items
// Please note that "CSS width breakpoints" (which are only 4) !== "navbar breakpoints" (which are as many as the number of items on the navbar)
function measureLinks ( ) {
numOfItems = 0 ;
totalSpace = 0 ;
closingTime = 1000 ;
breakWidths = [ ] ;
// Adds the width of a navItem in order to create breakpoints for the navbar
function addWidth ( i , w ) {
totalSpace += w ;
numOfItems += 1 ;
breakWidths . push ( totalSpace ) ;
}
// Measures the width of hidden links by making a temporary clone of them and positioning under visible links
function hiddenWidth ( obj ) {
var clone = obj . clone ( ) ;
clone . css ( "visibility" , "hidden" ) ;
$vlinks . append ( clone ) ;
addWidth ( 0 , clone . outerWidth ( ) ) ;
clone . remove ( ) ;
}
// Measure both visible and hidden links widths
$vlinks . children ( ) . outerWidth ( addWidth ) ;
$hlinks . children ( ) . each ( function ( ) { hiddenWidth ( $ ( this ) ) } ) ;
}
2017-09-28 23:42:38 +02:00
// Get initial state
2021-10-02 11:28:46 +02:00
measureLinks ( ) ;
var winWidth = $ ( window ) . width ( ) ;
// Set the last measured CSS width breakpoint: 0: <768px, 1: <1024px, 2: < 1280px, 3: >= 1280px.
var lastBreakpoint = winWidth < 768 ? 0 : winWidth < 1024 ? 1 : winWidth < 1280 ? 2 : 3 ;
2017-09-28 23:42:38 +02:00
2021-10-02 11:28:46 +02:00
var availableSpace , numOfVisibleItems , requiredSpace , timer , timer2 ;
2017-09-28 23:42:38 +02:00
function check ( ) {
2021-10-02 11:28:46 +02:00
winWidth = $ ( window ) . width ( ) ;
// Set the current CSS width breakpoint: 0: <768px, 1: <1024px, 2: < 1280px, 3: >= 1280px.
var curBreakpoint = winWidth < 768 ? 0 : winWidth < 1024 ? 1 : winWidth < 1280 ? 2 : 3 ;
// If current breakpoint is different from last measured breakpoint, measureLinks again
if ( curBreakpoint !== lastBreakpoint ) measureLinks ( ) ;
// Set the last measured CSS width breakpoint with the current breakpoint
lastBreakpoint = curBreakpoint ;
2017-09-28 23:42:38 +02:00
// Get instant state
numOfVisibleItems = $vlinks . children ( ) . length ;
2021-10-02 11:28:46 +02:00
// Decrease the width of visible elements from the nav innerWidth to find out the available space for navItems
availableSpace = /* nav */ $nav . innerWidth ( )
- /* logo */ // ($logo.length !== 0 ? $logo.outerWidth(true) : 0)
- /* title */ // $title.outerWidth(true)
- /* search */ ( $search . length !== 0 ? $search . outerWidth ( true ) : 0 )
- /* toggle */ ( numOfVisibleItems !== breakWidths . length ? $btn . outerWidth ( true ) : 0 )
- /* toggle-lang */ ( $btn2 . outerWidth ( true ) ) ;
2017-09-28 23:42:38 +02:00
requiredSpace = breakWidths [ numOfVisibleItems - 1 ] ;
2021-10-02 11:28:46 +02:00
// There is not enought space
2017-09-28 23:42:38 +02:00
if ( requiredSpace > availableSpace ) {
2021-10-02 11:28:46 +02:00
$vlinks . children ( ) . last ( ) . prependTo ( $hlinks ) ;
2017-09-28 23:42:38 +02:00
numOfVisibleItems -= 1 ;
check ( ) ;
2021-10-02 11:28:46 +02:00
// There is more than enough space. If only one element is hidden, add the toggle width to the available space
} else if ( availableSpace + ( numOfVisibleItems === breakWidths . length - 1 ? $btn . outerWidth ( true ) : 0 ) > breakWidths [ numOfVisibleItems ] ) {
$hlinks . children ( ) . first ( ) . appendTo ( $vlinks ) ;
2017-09-28 23:42:38 +02:00
numOfVisibleItems += 1 ;
check ( ) ;
2016-10-30 01:02:14 +02:00
}
2017-09-28 23:42:38 +02:00
// Update the button accordingly
2021-10-02 11:28:46 +02:00
$btn . attr ( "count" , numOfItems - numOfVisibleItems ) ;
2017-09-28 23:42:38 +02:00
if ( numOfVisibleItems === numOfItems ) {
2021-10-02 11:28:46 +02:00
$btn . addClass ( 'hidden' ) ;
} else $btn . removeClass ( 'hidden' ) ;
2016-10-30 01:02:14 +02:00
}
2017-09-28 23:42:38 +02:00
// Window listeners
$ ( window ) . resize ( function ( ) {
check ( ) ;
} ) ;
2021-10-02 11:28:46 +02:00
$btn . on ( 'click' , function ( ) {
if ( $hlinks . is ( ":visible" ) ) {
$hlinks . addClass ( 'hidden' ) ;
2017-09-28 23:42:38 +02:00
$ ( this ) . removeClass ( 'close' ) ;
2021-10-02 11:28:46 +02:00
clearTimeout ( timer ) ;
2017-09-28 23:42:38 +02:00
} else {
2021-10-02 11:28:46 +02:00
$hlinks . removeClass ( 'hidden' ) ;
2017-09-28 23:42:38 +02:00
$ ( this ) . addClass ( 'close' ) ;
$hlinks2 . addClass ( 'hidden' ) ;
$btn2 . removeClass ( 'close' ) ;
2021-10-02 11:28:46 +02:00
clearTimeout ( timer ) ;
2017-09-28 23:42:38 +02:00
}
} ) ;
2021-10-02 11:28:46 +02:00
$hlinks . on ( 'mouseleave' , function ( ) {
// Mouse has left, start the timer
timer = setTimeout ( function ( ) {
$hlinks . addClass ( 'hidden' ) ;
2017-09-28 23:42:38 +02:00
} , closingTime ) ;
} ) . on ( 'mouseenter' , function ( ) {
2021-10-02 11:28:46 +02:00
// Mouse is back, cancel the timer
clearTimeout ( timer ) ;
2017-09-28 23:42:38 +02:00
} )
$btn2 . on ( 'click' , function ( ) {
if ( $hlinks2 . is ( ":visible" ) ) {
$hlinks2 . addClass ( 'hidden' ) ;
$ ( this ) . removeClass ( 'close' ) ;
2021-10-02 11:28:46 +02:00
clearTimeout ( timer2 ) ;
2017-09-28 23:42:38 +02:00
} else {
$hlinks2 . removeClass ( 'hidden' ) ;
$ ( this ) . addClass ( 'close' ) ;
2021-10-02 11:28:46 +02:00
$hlinks . addClass ( 'hidden' ) ;
$btn . removeClass ( 'close' ) ;
clearTimeout ( timer2 ) ;
2017-09-28 23:42:38 +02:00
}
} ) ;
2016-10-30 01:02:14 +02:00
2017-09-28 23:42:38 +02:00
$hlinks2 . on ( 'mouseleave' , function ( ) {
2021-10-02 11:28:46 +02:00
// Mouse has left, start the timer
2017-09-28 23:42:38 +02:00
timer2 = setTimeout ( function ( ) {
$hlinks2 . addClass ( 'hidden' ) ;
} , closingTime ) ;
} ) . on ( 'mouseenter' , function ( ) {
2021-10-02 11:28:46 +02:00
// Mouse is back, cancel the timer
2017-09-28 23:42:38 +02:00
clearTimeout ( timer2 ) ;
} )
2016-10-30 01:02:14 +02:00
2021-10-02 11:28:46 +02:00
// check if page has a logo
if ( $logoImg . length !== 0 ) {
// check if logo is not loaded
if ( ! ( $logoImg [ 0 ] . complete || $logoImg [ 0 ] . naturalWidth !== 0 ) ) {
// if logo is not loaded wait for logo to load or fail to check
$logoImg . one ( "load error" , check ) ;
// if logo is already loaded just check
} else check ( ) ;
// if page does not have a logo just check
} else check ( ) ;
2016-10-30 01:02:14 +02:00
} ) ;