ycategories-presentation/extensions/menu/deck.menu.js

188 lines
4.9 KiB
JavaScript
Raw Normal View History

2011-08-08 03:19:46 +00:00
/*!
2011-10-08 05:03:50 +00:00
Deck JS - deck.menu
2011-08-08 03:19:46 +00:00
Copyright (c) 2011 Caleb Troughton
Dual licensed under the MIT license and GPL license.
https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
https://github.com/imakewebthings/deck.js/blob/master/GPL-license.txt
*/
/*
This module adds the methods and key binding to show and hide a menu of all
slides in the deck. The deck menu state is indicated by the presence of a class
on the deck container.
*/
(function($, deck, undefined) {
var $d = $(document),
rootSlides; // Array of top level slides
2011-06-07 13:07:00 +00:00
2011-08-08 03:19:46 +00:00
/*
Extends defaults/options.
options.classes.menu
This class is added to the deck container when showing the slide menu.
options.keys.menu
The numeric keycode used to toggle between showing and hiding the slide
menu.
2011-08-26 03:30:16 +00:00
options.touch.doubletapWindow
Two consecutive touch events within this number of milliseconds will
be considered a double tap, and will toggle the menu on touch devices.
2011-08-08 03:19:46 +00:00
*/
$.extend(true, $[deck].defaults, {
classes: {
menu: 'deck-menu'
},
keys: {
menu: 77 // m
2011-08-26 03:30:16 +00:00
},
touch: {
doubletapWindow: 400
2011-08-08 03:19:46 +00:00
}
});
2011-06-07 13:07:00 +00:00
2011-08-08 03:19:46 +00:00
/*
jQuery.deck('showMenu')
Shows the slide menu by adding the class specified by the menu class option
to the deck container.
*/
$[deck]('extend', 'showMenu', function() {
var $c = $[deck]('getContainer'),
opts = $[deck]('getOptions');
if ($c.hasClass(opts.classes.menu)) return;
// Hide through loading class to short-circuit transitions (perf)
$c.addClass([opts.classes.loading, opts.classes.menu].join(' '));
2011-10-23 05:38:32 +00:00
/* Forced to do this in JS until CSS learns second-grade math. Save old
style value for restoration when menu is hidden. */
if (Modernizr.csstransforms) {
$.each(rootSlides, function(i, $slide) {
$slide.data('oldStyle', $slide.attr('style'));
$slide.css({
'position': 'absolute',
'left': ((i % 4) * 25) + '%',
'top': (Math.floor(i / 4) * 25) + '%'
});
});
}
// Need to ensure the loading class renders first, then remove
window.setTimeout(function() {
$c.removeClass(opts.classes.loading)
.scrollTop($[deck]('getSlide').offset().top);
}, 0);
2011-06-07 13:07:00 +00:00
});
2011-08-08 03:19:46 +00:00
/*
jQuery.deck('hideMenu')
Hides the slide menu by removing the class specified by the menu class
option from the deck container.
*/
$[deck]('extend', 'hideMenu', function() {
var $c = $[deck]('getContainer'),
opts = $[deck]('getOptions');
if (!$c.hasClass(opts.classes.menu)) return;
$c.removeClass(opts.classes.menu);
$c.addClass(opts.classes.loading);
2011-10-23 05:38:32 +00:00
/* Restore old style value */
if (Modernizr.csstransforms) {
$.each(rootSlides, function(i, $slide) {
var oldStyle = $slide.data('oldStyle');
$slide.attr('style', oldStyle ? oldStyle : '');
});
}
window.setTimeout(function() {
$c.removeClass(opts.classes.loading).scrollTop(0);
}, 0);
2011-06-07 13:07:00 +00:00
});
2011-08-08 03:19:46 +00:00
/*
jQuery.deck('toggleMenu')
Toggles between showing and hiding the slide menu.
*/
$[deck]('extend', 'toggleMenu', function() {
$[deck]('getContainer').hasClass($[deck]('getOptions').classes.menu) ?
$[deck]('hideMenu') : $[deck]('showMenu');
2011-06-07 13:07:00 +00:00
});
2011-06-07 15:08:50 +00:00
$d.bind('deck.init', function() {
2011-08-26 03:30:16 +00:00
var opts = $[deck]('getOptions'),
touchEndTime = 0,
currentSlide,
slideTest = $.map([
opts.classes.before,
opts.classes.previous,
opts.classes.current,
opts.classes.next,
opts.classes.after
], function(el, i) {
return '.' + el;
}).join(', ');
2011-10-23 05:38:32 +00:00
// Build top level slides array
rootSlides = [];
$.each($[deck]('getSlides'), function(i, $el) {
if (!$el.parentsUntil(opts.selectors.container, slideTest).length) {
rootSlides.push($el);
}
});
2011-08-26 03:30:16 +00:00
2011-08-08 03:19:46 +00:00
// Bind key events
$d.unbind('keydown.deckmenu').bind('keydown.deckmenu', function(e) {
2011-08-30 04:15:28 +00:00
if (e.which === opts.keys.menu || $.inArray(e.which, opts.keys.menu) > -1) {
2011-08-08 03:19:46 +00:00
$[deck]('toggleMenu');
e.preventDefault();
2011-06-07 13:07:00 +00:00
}
});
2011-08-26 03:30:16 +00:00
// Double tap to toggle slide menu for touch devices
$[deck]('getContainer').unbind('touchstart.deckmenu').bind('touchstart.deckmenu', function(e) {
currentSlide = $[deck]('getSlide');
})
.unbind('touchend.deckmenu').bind('touchend.deckmenu', function(e) {
2011-08-26 03:30:16 +00:00
var now = Date.now();
// Ignore this touch event if it caused a nav change (swipe)
if (currentSlide !== $[deck]('getSlide')) return;
2011-08-26 03:30:16 +00:00
if (now - touchEndTime < opts.touch.doubletapWindow) {
$[deck]('toggleMenu');
e.preventDefault();
}
2011-08-26 03:30:16 +00:00
touchEndTime = now;
});
// Selecting slides from the menu
$.each($[deck]('getSlides'), function(i, $s) {
$s.unbind('click.deckmenu').bind('click.deckmenu', function(e) {
if (!$[deck]('getContainer').hasClass(opts.classes.menu)) return;
$[deck]('go', i);
$[deck]('hideMenu');
e.stopPropagation();
e.preventDefault();
});
});
})
.bind('deck.change', function(e, from, to) {
2011-08-23 07:12:25 +00:00
var container = $[deck]('getContainer');
2011-08-23 07:12:25 +00:00
if (container.hasClass($[deck]('getOptions').classes.menu)) {
container.scrollTop($[deck]('getSlide', to).offset().top);
}
2011-06-07 13:07:00 +00:00
});
2011-06-07 15:08:50 +00:00
})(jQuery, 'deck');
2011-06-07 13:07:00 +00:00