portal html css js resource

jquery.mmenu.js 17KB

    /* * jQuery mmenu 1.3.1 * * Copyright (c) 2013 Fred Heusschen * www.frebsite.nl * * Dual licensed under the MIT and GPL licenses. * http://en.wikipedia.org/wiki/MIT_License * http://en.wikipedia.org/wiki/GNU_General_Public_License */ (function( $ ) { // Global nodes var $wndw = null, $html = null, $body = null, $page = null, $blck = null; var $scrollTopNode = null; // Global vars var _serialnr = 0; $.fn.mmenu = function( opts ) { if ( !$wndw ) { $wndw = $(window); $html = $('html'); $body = $('body'); } opts = extendOptions( opts ); opts = $.extend( true, {}, $.fn.mmenu.defaultOptions, opts ); opts = complementOptions( opts ); $html[ opts.configuration.hardwareAcceleration ? 'addClass' : 'removeClass' ]( cls( 'accelerated' ) ); return this.each( function() { // STORE VARIABLES var $menu = $(this), _opened = false, _direction = ( opts.slidingSubmenus ) ? 'horizontal' : 'vertical'; _serialnr++; // INIT PAGE, MENU, LINKS & LABELS $page = _initPage( $page, opts.configuration ); $blck = _initBlocker( $blck, $menu, opts.configuration ); $menu = _initMenu( $menu, opts.configuration ); _initSubmenus( $menu, _direction, _serialnr ); _initLinks( $menu, opts.onClick, opts.configuration ); _initCounters( $menu, opts.counters, opts.configuration ); _initSearch( $menu, opts.searchfield ); _initOpenClose( $menu, $page ); // BIND EVENTS var $subs = $menu.find( 'ul' ); $menu.add( $subs ) .bind( evt( 'toggle' ) + ' ' + evt( 'open' ) + ' ' + evt( 'close' ), function( e ) { e.preventDefault(); e.stopPropagation(); } ); // menu-events $menu .bind( evt( 'toggle' ), function( e ) { return $menu.triggerHandler( evt( _opened ? 'close' : 'open' ) ); } ) .bind( evt( 'open' ), function( e ) { if ( _opened ) { return false; } _opened = true; return openMenu( $menu, opts.position ); } ) .bind( evt( 'close' ), function( e ) { if ( !_opened ) { return false; } _opened = false; return closeMenu( $menu, opts ); } ); // submenu-events if ( _direction == 'horizontal' ) { $subs .bind( evt( 'toggle' ), function( e ) { return $(this).triggerHandler( evt( 'open' ) ); } ) .bind( evt( 'open' ), function( e ) { return openSubmenuHorizontal( $(this), opts ); } ) .bind( evt( 'close' ), function( e ) { return closeSubmenuHorizontal( $(this), opts ); } ); } else { $subs .bind( evt( 'toggle' ), function( e ) { var $t = $(this); return $t.triggerHandler( evt( ( $t.parent().hasClass( cls( 'opened' ) ) ) ? 'close' : 'open' ) ); } ) .bind( evt( 'open' ), function( e ) { $(this).parent().addClass( cls( 'opened' ) ); return 'open'; } ) .bind( evt( 'close' ), function( e ) { $(this).parent().removeClass( cls( 'opened' ) ); return 'close'; } ); } } ); }; $.fn.mmenu.defaultOptions = { position : 'right', slidingSubmenus : true, counters : { add : false, count : true }, searchfield : { add : false, search : true, showLinksOnly : true, placeholder : 'Search', noResults : 'No results found.' }, onClick : { close : true, delayPageload : true, blockUI : false }, configuration : { hardwareAcceleration: true, selectedClass : 'Selected', labelClass : 'Label', counterClass : 'Counter', pageNodetype : 'div', menuNodetype : 'nav', slideDuration : 500 } }; $.fn.mmenu.debug = function( msg ) { if ( typeof console != 'undefined' && typeof console.log != 'undefined' ) { console.log( 'MMENU: ' + msg ); } }; $.fn.mmenu.deprecated = function( depr, repl ) { if ( typeof console != 'undefined' && typeof console.warn != 'undefined' ) { console.warn( 'MMENU: ' + depr + ' is deprecated, use ' + repl + ' instead.' ); } }; function extendOptions( o ) { if ( typeof o == 'string' ) { if ( o == 'left' || o == 'right' ) { o = { position: o }; } } else if ( typeof o != 'object' ) { o = {}; } // DEPRECATED if ( typeof o.addCounters != 'undefined' ) { $.fn.mmenu.deprecated( 'addCounters-option', 'counters.add-option' ); o.counters = { add: o.addCounters }; } if ( typeof o.closeOnClick != 'undefined' ) { $.fn.mmenu.deprecated( 'closeOnClick-option', 'onClick.close-option' ); o.onClick = { close: o.closeOnClick }; } // /DEPRECATED // Counters if ( typeof o.counters == 'boolean' ) { o.counters = { add : o.counters, count : o.counters }; } else if ( typeof o.counters != 'object' ) { o.counters = {}; } // OnClick if ( typeof o.onClick == 'boolean' ) { o.onClick = { close : o.onClick }; } else if ( typeof o.onClick != 'object' ) { o.onClick = {}; } // Search if ( typeof o.searchfield == 'boolean' ) { o.searchfield = { add : o.searchfield, search : o.searchfield }; } else if ( typeof o.searchfield == 'string' ) { o.searchfield = { add : true, search : true, placeholder : o.searchfield }; } else if ( typeof o.searchfield != 'object' ) { o.searchfield = {}; } return o; } function complementOptions( o ) { if ( typeof o.onClick.delayPageload == 'boolean' ) { o.onClick.delayPageload = ( o.onClick.delayPageload ) ? o.configuration.slideDuration : 0; } return o; } function _initPage( $p, conf ) { if ( !$p ) { $p = $('> ' + conf.pageNodetype, $body); if ( $p.length > 1 ) { $p = $p.wrapAll( '<' + conf.pageNodetype + ' />' ).parent(); } $p.addClass( cls( 'page' ) ); } return $p; } function _initMenu( $m, conf ) { if ( !$m.is( conf.menuNodetype ) ) { $m = $( '<' + conf.menuNodetype + ' />' ).append( $m ); } // $_dummy = $( '<div class="mmenu-dummy" />' ).insertAfter( $m ).hide(); $m.addClass( cls( '' ).slice( 0, -1 ) ).prependTo( 'body' ); // Refactor selected class $('li.' + conf.selectedClass, $m).removeClass( conf.selectedClass ).addClass( cls( 'selected' ) ); // Refactor label class $('li.' + conf.labelClass, $m).removeClass( conf.labelClass ).addClass( cls( 'label' ) ); return $m; } function _initSubmenus( $m, direction, serial ) { $m.addClass( cls( direction ) ); $( 'ul ul', $m ) .addClass( cls( 'submenu' ) ) .each( function( i ) { var $t = $(this) $a = $t.parent().find( '> a, > span' ), id = $t.attr( 'id' ) || cls( 's' + serial + '-' + i ); $t.attr( 'id', id ); var $btn = $( '<a class="' + cls( 'subopen' ) + '" href="#' + id + '" />' ).insertBefore( $a ); if ( !$a.is( 'a' ) ) { $btn.addClass( cls( 'fullsubopen' ) ); } if ( direction == 'horizontal' ) { var $p = $t.parent().parent(), id = $p.attr( 'id' ) || cls( 'p' + serial + '-' + i ); $p.attr( 'id', id ); $t.prepend( '<li class="' + cls( 'subtitle' ) + '"><a class="' + cls( 'subclose' ) + '" href="#' + id + '">' + $a.text() + '</a></li>' ); } } ); if ( direction == 'horizontal' ) { // Add opened-classes $('li.' + cls( 'selected' ), $m) .parents( 'li.' + cls( 'selected' ) ).removeClass( cls( 'selected' ) ) .end().each( function() { var $t = $(this), $u = $t.find( '> ul' ); if ( $u.length ) { $t.parent().addClass( cls( 'subopened' ) ); $u.addClass( cls( 'opened' ) ); } } ) .parent().addClass( cls( 'opened' ) ) .parents( 'ul' ).addClass( cls( 'subopened' ) ); if ( !$('ul.' + cls( 'opened' ), $m).length ) { $('ul', $m).not( '.' + cls( 'submenu' ) ).addClass( cls( 'opened' ) ); } // Rearrange markup $('ul ul', $m).appendTo( $m ); } else { // Replace Selected-class with opened-class in parents from .Selected $('li.' + cls( 'selected' ), $m) .addClass( cls( 'opened' ) ) .parents( '.' + cls( 'selected' ) ).removeClass( cls( 'selected' ) ); } } function _initBlocker( $b, $m, conf ) { if ( !$b ) { $b = $( '<div id="' + cls( 'blocker' ) + '" />' ).appendTo( $body ); } click( $b, function() { $m.trigger( evt( 'close' ) ); } ); return $b; } function _initLinks( $m, onClick, conf ) { if ( onClick.close ) { var $a = $('a', $m) .not( '.' + cls( 'subopen' ) ) .not( '.' + cls( 'subclose' ) ); click( $a, function() { var $t = $(this), href = $t.attr( 'href' ); $m.trigger( evt( 'close' ) ); $a.parent().removeClass( cls( 'selected' ) ); $t.parent().addClass( cls( 'selected' ) ); if ( onClick.blockUI && href.slice( 0, 1 ) != '#' ) { $html.addClass( cls( 'blocking' ) ); } if ( href != '#' ) { setTimeout( function() { window.location.href = href; }, onClick.delayPageload ); } } ); } } function _initCounters( $m, counters, conf ) { // Refactor counter class $('em.' + conf.counterClass, $m).removeClass( conf.counterClass ).addClass( cls( 'counter' ) ); // Add counters if ( counters.add ) { $('.' + cls( 'submenu' ), $m).each( function() { var $s = $(this), id = $s.attr( 'id' ); if ( id && id.length ) { var $c = $( '<em class="' + cls( 'counter' ) + '" />' ), $a = $('a.' + cls( 'subopen' ), $m).filter( '[href="#' + id + '"]' ); if ( !$a.parent().find( 'em.' + cls( 'counter' ) ).length ) { $a.before( $c ); } } } ); } // Bind count event if ( counters.count ) { $('em.' + cls( 'counter' ), $m).each( function() { var $c = $(this), $s = $('ul' + $c.next().attr( 'href' ), $m); $c.bind( evt( 'count' ), function( e ) { e.preventDefault(); e.stopPropagation(); var $lis = $s.children() .not( '.' + cls( 'label' ) ) .not( '.' + cls( 'subtitle' ) ) .not( '.' + cls( 'noresult' ) ) .not( '.' + cls( 'noresults' ) ); $c.html( $lis.length ); } ); } ).trigger( evt( 'count' ) ); } } function _initSearch( $m, search ) { if ( search.add ) { var $s = $( '<div class="' + cls( 'search' ) + '" />' ).prependTo( $m ); $s.append( '<input placeholder="' + search.placeholder + '" type="text" autocomplete="off" />' ); if ( search.noResults ) { $('ul', $m).not( '.' + cls( 'submenu' ) ).append( '<li class="' + cls( 'noresults' ) + '">' + search.noResults + '</li>' ); } } if ( search.search ) { var $s = $('div.' + cls( 'search' ), $m), $i = $('input', $s); var $labels = $('li.' + cls( 'label' ), $m), $counters = $('em.' + cls( 'counter' ), $m), $items = $('li', $m) .not( '.' + cls( 'subtitle' ) ) .not( '.' + cls( 'label' ) ) .not( '.' + cls( 'noresults' ) ); var _searchText = '> a'; if ( !search.showLinksOnly ) { _searchText += ', > span'; } $i.bind( evt( 'keyup' ), function() { var query = $i.val().toLowerCase(); // search through items $items.add( $labels ).addClass( cls( 'noresult' ) ); $items.each( function() { var $t = $(this); if ( $(_searchText, $t).text().toLowerCase().indexOf( query ) > -1 ) { $t.add( $t.prevAll( '.' + cls( 'label' ) ).first() ).removeClass( cls( 'noresult' ) ); } } ); // update parent for submenus $( $('ul.' + cls( 'submenu' ), $m).get().reverse() ).each( function() { var $t = $(this), $p = null, id = $t.attr( 'id' ), $i = $t.find( 'li' ) .not( '.' + cls( 'subtitle' ) ) .not( '.' + cls( 'label' ) ) .not( '.' + cls( 'noresult' ) ); if ( id && id.length ) { var $p = $('a.' + cls( 'subopen' ), $m).filter( '[href="#' + id + '"]' ).parent(); } if ( $i.length ) { if ( $p ) { $p.removeClass( cls( 'noresult' ) ); $p.removeClass( cls( 'nosubresult' ) ); } } else { $t.trigger( evt( 'close' ) ); if ( $p ) { $p.addClass( cls( 'nosubresult' ) ); } } } ); // show/hide no results message $m[ $items.not( '.' + cls( 'noresult' ) ).length ? 'removeClass' : 'addClass' ]( cls( 'noresults' ) ); // update counters $counters.trigger( evt( 'count' ) ); } ); } } function _initOpenClose( $m, $p ) { // toggle menu var id = $m.attr( 'id' ); if ( id && id.length ) { click( 'a[href="#' + id + '"]', function() { $m.trigger( evt( 'toggle' ) ); } ); } // close menu var id = $p.attr( 'id' ); if ( id && id.length ) { click( 'a[href="#' + id + '"]', function() { $m.trigger( evt( 'close' ) ); } ); } // open submenu click( $('a.' + cls( 'subopen' ) + ', ' + 'a.' + cls( 'subclose' ), $m), function() { $( $(this).attr( 'href' ) ).trigger( evt( 'toggle' ) ); } ); } function openMenu( $m, p ) { var _scrollTop = findScrollTop(); // resize page var _w = 0; $wndw.bind( evt( 'resize' ), function( e ) { var nw = $wndw.width(); if ( nw != _w ) { _w = nw; $page .attr( 'style', $page.data( dta( 'style' ) ) ) .width( nw ); } } ); // store style and position $page .data( dta( 'style' ), $page.attr( 'style' ) || '' ) .data( dta( 'scrollTop' ), _scrollTop ) .width( $page.outerWidth() ) .css( 'top', -_scrollTop ); // open $m.addClass( cls( 'opened' ) ); $html.addClass( cls( 'opened' ) ).addClass( cls( p ) ); setTimeout( function() { // opened $html.addClass( cls( 'opening' ) ); }, 25 ); return 'open'; } function closeMenu( $m, o ) { // close $html.removeClass( cls( 'opening' ) ); setTimeout( function() { // closed $html.removeClass( cls( 'opened' ) ).removeClass( cls( o.position ) ); $m.removeClass( cls( 'opened' ) ); // restore style and position $page.attr( 'style', $page.data( dta( 'style' ) ) ); $wndw.unbind( evt( 'resize' ) ); if ( $scrollTopNode ) { $scrollTopNode.scrollTop( $page.data( dta( 'scrollTop' ) ) ); } }, o.configuration.slideDuration + 25 ); return 'close'; } function openSubmenuHorizontal( $t, o ) { $t.prevAll( 'ul' ).addClass( cls( 'subopened' ) ); $t.nextAll( 'ul' ).removeClass( cls( 'subopened' ) ); $t.removeClass( cls( 'subopened' ) ).addClass( cls( 'opened' ) ); setTimeout( function() { $t.nextAll( 'ul' ).removeClass( cls( 'opened' ) ); }, o.configuration.slideDuration + 25 ); return 'open'; } function closeSubmenuHorizontal( $t, o ) { $t.prevAll( 'ul.' + cls( 'opened' ) ).first().trigger( evt( 'open' ) ); return 'close'; } function findScrollTop() { if ( !$scrollTopNode ) { if ( $('html').scrollTop() != 0 ) { $scrollTopNode = $('html'); } else if ( $('body').scrollTop() != 0 ) { $scrollTopNode = $('body'); } } return ( $scrollTopNode ) ? $scrollTopNode.scrollTop() - 1 : 0; } function click( $b, fn ) { if ( typeof $b == 'string' ) { $b = $( $b ); } $b.bind( evt( 'click' ), function( e ) { e.preventDefault(); e.stopPropagation(); fn.call( this, e ); } ); } function cls( c ) { return 'mmenu-' + c; } function dta( d ) { return 'mmenu-' + d; } function evt( e ) { return e + '.mmenu'; } })( jQuery );