2015-10-01 16:00:26 +02:00
; ( function ( $ , window , document , undefined ) {
'use strict' ;
Foundation . libs . topbar = {
name : 'topbar' ,
2018-02-18 00:45:27 +01:00
version : '5.5.3master' ,
2015-10-01 16:00:26 +02:00
settings : {
index : 0 ,
start _offset : 0 ,
sticky _class : 'sticky' ,
custom _back _text : true ,
back _text : 'Back' ,
mobile _show _parent _link : true ,
is _hover : true ,
scrolltop : true , // jump to top when sticky nav menu toggle is clicked
sticky _on : 'all' ,
dropdown _autoclose : true
} ,
init : function ( section , method , options ) {
Foundation . inherit ( this , 'add_custom_rule register_media throttle' ) ;
var self = this ;
self . register _media ( 'topbar' , 'foundation-mq-topbar' ) ;
this . bindings ( method , options ) ;
self . S ( '[' + this . attr _name ( ) + ']' , this . scope ) . each ( function ( ) {
var topbar = $ ( this ) ,
settings = topbar . data ( self . attr _name ( true ) + '-init' ) ,
section = self . S ( 'section, .top-bar-section' , this ) ;
topbar . data ( 'index' , 0 ) ;
var topbarContainer = topbar . parent ( ) ;
if ( topbarContainer . hasClass ( 'fixed' ) || self . is _sticky ( topbar , topbarContainer , settings ) ) {
self . settings . sticky _class = settings . sticky _class ;
self . settings . sticky _topbar = topbar ;
topbar . data ( 'height' , topbarContainer . outerHeight ( ) ) ;
topbar . data ( 'stickyoffset' , topbarContainer . offset ( ) . top ) ;
} else {
topbar . data ( 'height' , topbar . outerHeight ( ) ) ;
}
if ( ! settings . assembled ) {
self . assemble ( topbar ) ;
}
if ( settings . is _hover ) {
self . S ( '.has-dropdown' , topbar ) . addClass ( 'not-click' ) ;
} else {
self . S ( '.has-dropdown' , topbar ) . removeClass ( 'not-click' ) ;
}
// Pad body when sticky (scrolled) or fixed.
self . add _custom _rule ( '.f-topbar-fixed { padding-top: ' + topbar . data ( 'height' ) + 'px }' ) ;
if ( topbarContainer . hasClass ( 'fixed' ) ) {
self . S ( 'body' ) . addClass ( 'f-topbar-fixed' ) ;
}
} ) ;
} ,
is _sticky : function ( topbar , topbarContainer , settings ) {
var sticky = topbarContainer . hasClass ( settings . sticky _class ) ;
var smallMatch = matchMedia ( Foundation . media _queries . small ) . matches ;
var medMatch = matchMedia ( Foundation . media _queries . medium ) . matches ;
var lrgMatch = matchMedia ( Foundation . media _queries . large ) . matches ;
if ( sticky && settings . sticky _on === 'all' ) {
return true ;
}
if ( sticky && this . small ( ) && settings . sticky _on . indexOf ( 'small' ) !== - 1 ) {
if ( smallMatch && ! medMatch && ! lrgMatch ) { return true ; }
}
if ( sticky && this . medium ( ) && settings . sticky _on . indexOf ( 'medium' ) !== - 1 ) {
if ( smallMatch && medMatch && ! lrgMatch ) { return true ; }
}
if ( sticky && this . large ( ) && settings . sticky _on . indexOf ( 'large' ) !== - 1 ) {
if ( smallMatch && medMatch && lrgMatch ) { return true ; }
}
return false ;
} ,
toggle : function ( toggleEl ) {
var self = this ,
topbar ;
if ( toggleEl ) {
topbar = self . S ( toggleEl ) . closest ( '[' + this . attr _name ( ) + ']' ) ;
} else {
topbar = self . S ( '[' + this . attr _name ( ) + ']' ) ;
}
var settings = topbar . data ( this . attr _name ( true ) + '-init' ) ;
var section = self . S ( 'section, .top-bar-section' , topbar ) ;
if ( self . breakpoint ( ) ) {
if ( ! self . rtl ) {
section . css ( { left : '0%' } ) ;
$ ( '>.name' , section ) . css ( { left : '100%' } ) ;
} else {
section . css ( { right : '0%' } ) ;
$ ( '>.name' , section ) . css ( { right : '100%' } ) ;
}
self . S ( 'li.moved' , section ) . removeClass ( 'moved' ) ;
topbar . data ( 'index' , 0 ) ;
topbar
. toggleClass ( 'expanded' )
. css ( 'height' , '' ) ;
}
if ( settings . scrolltop ) {
if ( ! topbar . hasClass ( 'expanded' ) ) {
if ( topbar . hasClass ( 'fixed' ) ) {
topbar . parent ( ) . addClass ( 'fixed' ) ;
topbar . removeClass ( 'fixed' ) ;
self . S ( 'body' ) . addClass ( 'f-topbar-fixed' ) ;
}
} else if ( topbar . parent ( ) . hasClass ( 'fixed' ) ) {
if ( settings . scrolltop ) {
topbar . parent ( ) . removeClass ( 'fixed' ) ;
topbar . addClass ( 'fixed' ) ;
self . S ( 'body' ) . removeClass ( 'f-topbar-fixed' ) ;
window . scrollTo ( 0 , 0 ) ;
} else {
topbar . parent ( ) . removeClass ( 'expanded' ) ;
}
}
} else {
2018-02-15 18:42:07 +01:00
if ( self . is _sticky ( topbar , topbar . parent ( ) , settings ) && topbar . parent ( ) . offset ( ) . top === 0 ) {
2015-10-01 16:00:26 +02:00
topbar . parent ( ) . addClass ( 'fixed' ) ;
}
if ( topbar . parent ( ) . hasClass ( 'fixed' ) ) {
if ( ! topbar . hasClass ( 'expanded' ) ) {
topbar . removeClass ( 'fixed' ) ;
topbar . parent ( ) . removeClass ( 'expanded' ) ;
self . update _sticky _positioning ( ) ;
} else {
topbar . addClass ( 'fixed' ) ;
topbar . parent ( ) . addClass ( 'expanded' ) ;
self . S ( 'body' ) . addClass ( 'f-topbar-fixed' ) ;
}
}
}
} ,
timer : null ,
events : function ( bar ) {
var self = this ,
S = this . S ;
S ( this . scope )
. off ( '.topbar' )
. on ( 'click.fndtn.topbar' , '[' + this . attr _name ( ) + '] .toggle-topbar' , function ( e ) {
e . preventDefault ( ) ;
self . toggle ( this ) ;
} )
. on ( 'click.fndtn.topbar contextmenu.fndtn.topbar' , '.top-bar .top-bar-section li a[href^="#"],[' + this . attr _name ( ) + '] .top-bar-section li a[href^="#"]' , function ( e ) {
2018-02-09 03:02:47 +01:00
var li = $ ( this ) . closest ( 'li' ) ,
topbar = li . closest ( '[' + self . attr _name ( ) + ']' ) ,
settings = topbar . data ( self . attr _name ( true ) + '-init' ) ;
if ( settings . dropdown _autoclose && settings . is _hover ) {
var hoverLi = $ ( this ) . closest ( '.hover' ) ;
hoverLi . removeClass ( 'hover' ) ;
}
if ( self . breakpoint ( ) && ! li . hasClass ( 'back' ) && ! li . hasClass ( 'has-dropdown' ) ) {
self . toggle ( ) ;
}
2015-10-01 16:00:26 +02:00
} )
. on ( 'click.fndtn.topbar' , '[' + this . attr _name ( ) + '] li.has-dropdown' , function ( e ) {
var li = S ( this ) ,
target = S ( e . target ) ,
topbar = li . closest ( '[' + self . attr _name ( ) + ']' ) ,
settings = topbar . data ( self . attr _name ( true ) + '-init' ) ;
if ( target . data ( 'revealId' ) ) {
self . toggle ( ) ;
return ;
}
if ( self . breakpoint ( ) ) {
return ;
}
if ( settings . is _hover && ! Modernizr . touch ) {
return ;
}
e . stopImmediatePropagation ( ) ;
2018-02-15 18:42:07 +01:00
if ( li . hasClass ( 'hover' ) && ( settings . is _hover || li . children ( 'a' ) . first ( ) . hasClass ( 'last-clicked' ) ) ) {
2015-10-01 16:00:26 +02:00
li
. removeClass ( 'hover' )
. find ( 'li' )
. removeClass ( 'hover' ) ;
li . parents ( 'li.hover' )
. removeClass ( 'hover' ) ;
} else {
li . addClass ( 'hover' ) ;
$ ( li ) . siblings ( ) . removeClass ( 'hover' ) ;
if ( target [ 0 ] . nodeName === 'A' && target . parent ( ) . hasClass ( 'has-dropdown' ) ) {
e . preventDefault ( ) ;
2018-02-15 18:42:07 +01:00
if ( ! settings . is _hover ) {
topbar . find ( '.last-clicked' ) . removeClass ( 'last-clicked' ) ;
target . addClass ( 'last-clicked' ) ;
}
2015-10-01 16:00:26 +02:00
}
}
} )
. on ( 'click.fndtn.topbar' , '[' + this . attr _name ( ) + '] .has-dropdown>a' , function ( e ) {
if ( self . breakpoint ( ) ) {
e . preventDefault ( ) ;
var $this = S ( this ) ,
topbar = $this . closest ( '[' + self . attr _name ( ) + ']' ) ,
section = topbar . find ( 'section, .top-bar-section' ) ,
dropdownHeight = $this . next ( '.dropdown' ) . outerHeight ( ) ,
$selectedLi = $this . closest ( 'li' ) ;
topbar . data ( 'index' , topbar . data ( 'index' ) + 1 ) ;
$selectedLi . addClass ( 'moved' ) ;
if ( ! self . rtl ) {
section . css ( { left : - ( 100 * topbar . data ( 'index' ) ) + '%' } ) ;
section . find ( '>.name' ) . css ( { left : 100 * topbar . data ( 'index' ) + '%' } ) ;
} else {
section . css ( { right : - ( 100 * topbar . data ( 'index' ) ) + '%' } ) ;
section . find ( '>.name' ) . css ( { right : 100 * topbar . data ( 'index' ) + '%' } ) ;
}
topbar . css ( 'height' , $this . siblings ( 'ul' ) . outerHeight ( true ) + topbar . data ( 'height' ) ) ;
}
} ) ;
S ( window ) . off ( '.topbar' ) . on ( 'resize.fndtn.topbar' , self . throttle ( function ( ) {
self . resize . call ( self ) ;
2018-02-15 18:42:07 +01:00
} , 50 ) ) . trigger ( 'resize.fndtn.topbar' ) . on ( 'load' , function ( ) {
2015-10-01 16:00:26 +02:00
// Ensure that the offset is calculated after all of the pages resources have loaded
S ( this ) . trigger ( 'resize.fndtn.topbar' ) ;
} ) ;
S ( 'body' ) . off ( '.topbar' ) . on ( 'click.fndtn.topbar' , function ( e ) {
2018-02-15 18:42:07 +01:00
var parent = S ( e . target ) . closest ( 'li' ) . closest ( 'li.hover' ) ,
topbar = S ( e . target ) . closest ( '[' + self . attr _name ( ) + ']' ) ,
settings = topbar . data ( self . attr _name ( true ) + '-init' ) ;
2015-10-01 16:00:26 +02:00
if ( parent . length > 0 ) {
return ;
}
S ( '[' + self . attr _name ( ) + '] li.hover' ) . removeClass ( 'hover' ) ;
2018-02-15 18:42:07 +01:00
if ( settings && ! settings . is _hover ) {
S ( '[' + self . attr _name ( ) + '] a.last-clicked' ) . removeClass ( 'last-clicked' ) ;
}
2015-10-01 16:00:26 +02:00
} ) ;
// Go up a level on Click
S ( this . scope ) . on ( 'click.fndtn.topbar' , '[' + this . attr _name ( ) + '] .has-dropdown .back' , function ( e ) {
e . preventDefault ( ) ;
var $this = S ( this ) ,
topbar = $this . closest ( '[' + self . attr _name ( ) + ']' ) ,
section = topbar . find ( 'section, .top-bar-section' ) ,
settings = topbar . data ( self . attr _name ( true ) + '-init' ) ,
$movedLi = $this . closest ( 'li.moved' ) ,
$previousLevelUl = $movedLi . parent ( ) ;
topbar . data ( 'index' , topbar . data ( 'index' ) - 1 ) ;
if ( ! self . rtl ) {
section . css ( { left : - ( 100 * topbar . data ( 'index' ) ) + '%' } ) ;
section . find ( '>.name' ) . css ( { left : 100 * topbar . data ( 'index' ) + '%' } ) ;
} else {
section . css ( { right : - ( 100 * topbar . data ( 'index' ) ) + '%' } ) ;
section . find ( '>.name' ) . css ( { right : 100 * topbar . data ( 'index' ) + '%' } ) ;
}
if ( topbar . data ( 'index' ) === 0 ) {
topbar . css ( 'height' , '' ) ;
} else {
topbar . css ( 'height' , $previousLevelUl . outerHeight ( true ) + topbar . data ( 'height' ) ) ;
}
setTimeout ( function ( ) {
$movedLi . removeClass ( 'moved' ) ;
} , 300 ) ;
} ) ;
// Show dropdown menus when their items are focused
S ( this . scope ) . find ( '.dropdown a' )
. focus ( function ( ) {
$ ( this ) . parents ( '.has-dropdown' ) . addClass ( 'hover' ) ;
} )
. blur ( function ( ) {
2018-02-15 18:42:07 +01:00
$ ( this ) . removeClass ( 'last-clicked' ) . parents ( '.has-dropdown' ) . removeClass ( 'hover' ) ;
2015-10-01 16:00:26 +02:00
} ) ;
} ,
resize : function ( ) {
var self = this ;
self . S ( '[' + this . attr _name ( ) + ']' ) . each ( function ( ) {
2018-02-15 18:42:07 +01:00
var topbar = self . S ( this ) ;
2015-10-01 16:00:26 +02:00
var stickyContainer = topbar . parent ( '.' + self . settings . sticky _class ) ;
var stickyOffset ;
if ( ! self . breakpoint ( ) ) {
var doToggle = topbar . hasClass ( 'expanded' ) ;
topbar
. css ( 'height' , '' )
. removeClass ( 'expanded' )
. find ( 'li' )
. removeClass ( 'hover' ) ;
if ( doToggle ) {
self . toggle ( topbar ) ;
}
}
2018-02-15 18:42:07 +01:00
if ( self . is _sticky ( topbar , stickyContainer , self . settings ) ) {
2015-10-01 16:00:26 +02:00
if ( stickyContainer . hasClass ( 'fixed' ) ) {
// Remove the fixed to allow for correct calculation of the offset.
stickyContainer . removeClass ( 'fixed' ) ;
stickyOffset = stickyContainer . offset ( ) . top ;
if ( self . S ( document . body ) . hasClass ( 'f-topbar-fixed' ) ) {
stickyOffset -= topbar . data ( 'height' ) ;
}
topbar . data ( 'stickyoffset' , stickyOffset ) ;
stickyContainer . addClass ( 'fixed' ) ;
} else {
stickyOffset = stickyContainer . offset ( ) . top ;
topbar . data ( 'stickyoffset' , stickyOffset ) ;
}
}
} ) ;
} ,
breakpoint : function ( ) {
return ! matchMedia ( Foundation . media _queries [ 'topbar' ] ) . matches ;
} ,
small : function ( ) {
return matchMedia ( Foundation . media _queries [ 'small' ] ) . matches ;
} ,
medium : function ( ) {
return matchMedia ( Foundation . media _queries [ 'medium' ] ) . matches ;
} ,
large : function ( ) {
return matchMedia ( Foundation . media _queries [ 'large' ] ) . matches ;
} ,
assemble : function ( topbar ) {
var self = this ,
settings = topbar . data ( this . attr _name ( true ) + '-init' ) ,
section = self . S ( 'section, .top-bar-section' , topbar ) ;
// Pull element out of the DOM for manipulation
section . detach ( ) ;
self . S ( '.has-dropdown>a' , section ) . each ( function ( ) {
var $link = self . S ( this ) ,
$dropdown = $link . siblings ( '.dropdown' ) ,
url = $link . attr ( 'href' ) ,
$titleLi ;
if ( ! $dropdown . find ( '.title.back' ) . length ) {
2018-02-15 18:42:07 +01:00
if ( settings . mobile _show _parent _link === true && url ) {
2015-10-01 16:00:26 +02:00
$titleLi = $ ( '<li class="title back js-generated"><h5><a href="javascript:void(0)"></a></h5></li><li class="parent-link hide-for-medium-up"><a class="parent-link js-generated" href="' + url + '">' + $link . html ( ) + '</a></li>' ) ;
} else {
$titleLi = $ ( '<li class="title back js-generated"><h5><a href="javascript:void(0)"></a></h5>' ) ;
}
// Copy link to subnav
2018-02-15 18:42:07 +01:00
if ( settings . custom _back _text === true ) {
2015-10-01 16:00:26 +02:00
$ ( 'h5>a' , $titleLi ) . html ( settings . back _text ) ;
} else {
$ ( 'h5>a' , $titleLi ) . html ( '« ' + $link . html ( ) ) ;
}
$dropdown . prepend ( $titleLi ) ;
}
} ) ;
// Put element back in the DOM
section . appendTo ( topbar ) ;
// check for sticky
this . sticky ( ) ;
this . assembled ( topbar ) ;
} ,
assembled : function ( topbar ) {
topbar . data ( this . attr _name ( true ) , $ . extend ( { } , topbar . data ( this . attr _name ( true ) ) , { assembled : true } ) ) ;
} ,
height : function ( ul ) {
var total = 0 ,
self = this ;
$ ( '> li' , ul ) . each ( function ( ) {
total += self . S ( this ) . outerHeight ( true ) ;
} ) ;
return total ;
} ,
sticky : function ( ) {
var self = this ;
this . S ( window ) . on ( 'scroll' , function ( ) {
self . update _sticky _positioning ( ) ;
} ) ;
} ,
update _sticky _positioning : function ( ) {
var klass = '.' + this . settings . sticky _class ,
$window = this . S ( window ) ,
self = this ;
if ( self . settings . sticky _topbar && self . is _sticky ( this . settings . sticky _topbar , this . settings . sticky _topbar . parent ( ) , this . settings ) ) {
var distance = this . settings . sticky _topbar . data ( 'stickyoffset' ) + this . settings . start _offset ;
if ( ! self . S ( klass ) . hasClass ( 'expanded' ) ) {
if ( $window . scrollTop ( ) > ( distance ) ) {
if ( ! self . S ( klass ) . hasClass ( 'fixed' ) ) {
self . S ( klass ) . addClass ( 'fixed' ) ;
self . S ( 'body' ) . addClass ( 'f-topbar-fixed' ) ;
}
} else if ( $window . scrollTop ( ) <= distance ) {
if ( self . S ( klass ) . hasClass ( 'fixed' ) ) {
self . S ( klass ) . removeClass ( 'fixed' ) ;
self . S ( 'body' ) . removeClass ( 'f-topbar-fixed' ) ;
}
}
}
}
} ,
off : function ( ) {
this . S ( this . scope ) . off ( '.fndtn.topbar' ) ;
this . S ( window ) . off ( '.fndtn.topbar' ) ;
} ,
reflow : function ( ) { }
} ;
} ( jQuery , window , window . document ) ) ;