2016-03-21 21:01:19 +01:00
/ *
2020-06-06 16:30:54 +02:00
GreedyNav . js - http : //lukejacksonn.com/actuate
2017-02-14 04:14:10 +01:00
Licensed under the MIT license - http : //opensource.org/licenses/MIT
Copyright ( c ) 2015 Luke Jackson
2016-03-21 21:01:19 +01:00
* /
2020-06-06 16:30:54 +02:00
$ ( function ( ) {
2017-12-07 14:56:14 +01:00
var $btn = $ ( "nav.greedy-nav .greedy-nav__toggle" ) ;
var $vlinks = $ ( "nav.greedy-nav .visible-links" ) ;
var $hlinks = $ ( "nav.greedy-nav .hidden-links" ) ;
2020-08-28 22:41:29 +02:00
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' ) ;
var numOfItems , totalSpace , closingTime , breakWidths ;
2016-03-21 21:01:19 +01:00
2020-08-28 22:41:29 +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 = [ ] ;
2016-03-21 21:01:19 +01:00
2020-08-28 22:41:29 +02:00
// 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-02-14 04:14:10 +01:00
// Get initial state
2020-08-28 22:41:29 +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 ;
2016-03-21 21:01:19 +01:00
2020-06-06 16:30:54 +02:00
var availableSpace , numOfVisibleItems , requiredSpace , timer ;
2016-03-21 21:01:19 +01:00
2017-02-14 04:14:10 +01:00
function check ( ) {
2020-06-06 16:30:54 +02:00
2020-08-28 22:41:29 +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-02-14 04:14:10 +01:00
// Get instant state
numOfVisibleItems = $vlinks . children ( ) . length ;
2020-08-28 22:41:29 +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 ) ;
2017-02-14 04:14:10 +01:00
requiredSpace = breakWidths [ numOfVisibleItems - 1 ] ;
2016-03-21 21:01:19 +01:00
2020-06-06 16:30:54 +02:00
// There is not enought space
2017-02-14 04:14:10 +01:00
if ( requiredSpace > availableSpace ) {
2020-06-06 16:30:54 +02:00
$vlinks . children ( ) . last ( ) . prependTo ( $hlinks ) ;
2017-02-14 04:14:10 +01:00
numOfVisibleItems -= 1 ;
check ( ) ;
2020-08-28 22:41:29 +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 ] ) {
2020-06-06 16:30:54 +02:00
$hlinks . children ( ) . first ( ) . appendTo ( $vlinks ) ;
2017-02-14 04:14:10 +01:00
numOfVisibleItems += 1 ;
check ( ) ;
2016-03-21 21:01:19 +01:00
}
2017-02-14 04:14:10 +01:00
// Update the button accordingly
$btn . attr ( "count" , numOfItems - numOfVisibleItems ) ;
if ( numOfVisibleItems === numOfItems ) {
2020-06-06 16:30:54 +02:00
$btn . addClass ( 'hidden' ) ;
} else $btn . removeClass ( 'hidden' ) ;
2016-03-21 21:01:19 +01:00
}
2017-02-14 04:14:10 +01:00
// Window listeners
$ ( window ) . resize ( function ( ) {
check ( ) ;
} ) ;
2016-03-21 21:01:19 +01:00
2020-06-06 16:30:54 +02:00
$btn . on ( 'click' , function ( ) {
$hlinks . toggleClass ( 'hidden' ) ;
clearTimeout ( timer ) ;
2017-02-14 04:14:10 +01:00
} ) ;
2016-03-21 21:01:19 +01:00
2020-06-06 16:30:54 +02:00
$hlinks . on ( 'mouseleave' , function ( ) {
// Mouse has left, start the timer
timer = setTimeout ( function ( ) {
$hlinks . addClass ( 'hidden' ) ;
} , closingTime ) ;
} ) . on ( 'mouseenter' , function ( ) {
// Mouse is back, cancel the timer
clearTimeout ( timer ) ;
} )
2020-08-28 22:41:29 +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 ( ) ;
} ) ;