Skip to content

Commit

Permalink
+ Rewrote the main menu system to use hardware-accelerated CSS3 anima…
Browse files Browse the repository at this point in the history
…tions instead of jQuery to open menus and animate them. It still works the same in oldIE and other crappy browsers, without the animations of course. It's faster on all other devices, usability is MUCH better (transitions are way more natural delayers than JavaScript timers!), and in exchange for 250 extra bytes of CSS, it saves 100 lines of code for a whopping 1.2KB of JS. It's like early birthday present for me. (script.js, index.css)
  • Loading branch information
Nao committed Mar 6, 2014
1 parent 77f4d9e commit 8c58b91
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 65 deletions.
84 changes: 23 additions & 61 deletions core/javascript/script.js
Expand Up @@ -418,70 +418,32 @@ $.fn.ds = function ()

$.fn.mm = function ()
{
var menu_baseId = 0, menu_delay = [],

// Entering a menu entry?
menu_show_me = function ()
{
var
is_top = $(this).parent().hasClass('menu'),
is_visible = $('>ul', this).css('visibility') == 'visible';

$('>ul', this).css({
visibility: 'visible',
opacity: 1,
margin: is_top ? '0 ' + $('span', this).width() + 'px' : 0
});

if (!is_top || !$('>h4', this).addClass('hove').length)
$(this).addClass('hove').parentsUntil('.menu>li').filter('li').addClass('hove');

if (!is_visible)
$('>ul', this)
.css(is_top ? { marginTop: 5 } : { marginLeft: 0 })
.animate(is_top ? { marginTop: 0 } : { marginLeft: -5 });

clearTimeout(menu_delay[this.id.slice(2)]);

$(this).siblings('li').each(function () { menu_hide_children(this.id); });
},
this.find('li')
// Entering a menu entry?
.on('mouseenter focus', function ()
{
// Start the animation on its child.
$('>ul', this).addClass('anim');

// Leaving a menu entry?
menu_hide_me = function (e)
{
// The deepest level should hide the hover class immediately.
if (!$(this).children('ul').length)
$(this).children().andSelf().removeClass('hove');

// Are we leaving the menu entirely, and thus triggering the time threshold,
// or are we just switching to another non-context menu item?
var id = this.id, target_parent = $(e.relatedTarget).closest('.menu');
target_parent.length && !target_parent.hasClass('context') ? menu_hide_children(id) :
menu_delay[id.slice(2)] = setTimeout(function () { menu_hide_children(id); }, 300);
},

// Hide all children menus.
menu_hide_children = function (id)
{
$('#' + id).children().andSelf().removeClass('hove').find('ul').css({ visibility: 'hidden' }).css(is_ie8down ? '' : 'opacity', 0);
};
// Add hover effects to this menu entry's parent list. On top-level entries, add effect to the h4 tag only.
if (!$(this).parent().hasClass('menu') || !$('>h4', this).addClass('hove').length)
$(this).addClass('hove').parentsUntil('.menu>li').filter('li').addClass('hove');

this.each(function () {
var $elem = $(this);
$elem.find('li').each(function () {
$(this).attr('id', 'li' + menu_baseId++)
.on('mouseenter focus', menu_show_me)
.on('mouseleave blur', menu_hide_me)
// Disable double clicks...
.mousedown(false)
// Clicking a link will immediately close the menu -- giving a feeling of responsiveness.
.has('>a,>h4>a')
.click(function () {
$('.hove').removeClass('hove');
$elem.find('ul').css({ visibility: 'hidden' }).css(is_ie8down ? '' : 'opacity', 0);
});
$(this).siblings('li').children().andSelf().removeClass('hove anim');
})
// Leaving a menu entry? Then hide all of its children.
.on('mouseleave blur', function (e)
{
$(this).children().andSelf().removeClass('hove anim');
})
// Disable double clicks and text selection...
.mousedown(false)
// Clicking a link will immediately close the menu -- giving a feeling of responsiveness.
.find('>a,>h4>a')
.click(function () {
$('.hove').removeClass('hove');
$(this).parentsUntil('.menu').removeClass('anim');
});
});

// Make menu icons clickable by stealing the link from their neighbor.
$('.menu>li>span').each(function () { $(this).wrap($('<a/>').attr('href', $(this).next().find('a').attr('href'))); });
Expand Down
17 changes: 13 additions & 4 deletions core/skins/index.css
Expand Up @@ -869,7 +869,10 @@ input[type=file]
font-weight: 400
margin: 0 2px @is (ie7, 0, 10px) 0 // 10px gives more breathing space to the dropdown's arrow...

li ul
ul
opacity: 0
transition: opacity .3s ease, transform .3s ease, visibility .3s ease
transform: translate3d(0, 5px, 0)
display: block
clear: left
@if !ie[-7]
Expand All @@ -878,10 +881,9 @@ input[type=file]
position: absolute
z-index: 42
visibility: hidden
transition: opacity .3s ease
margin, padding: 0
border: 1px solid #bbb
@if ie9, chrome, firefox[20-] // Speed matters.
@if ie[9-], chrome, firefox[20-] // Speed matters.
background: #fcfcfc
box-shadow: inset 0 50px 50px rgba(232, 236, 232, .8), 2px 2px 3px 0 rgba(0,0,0, .2)
@else
Expand All @@ -890,7 +892,8 @@ input[type=file]
@endif
border-radius: 0 10px 10px 0

li li ul
ul ul
transform: translate3d(5px, 0, 0)
left: @is (ie6, 95%, 100%)
top: 0

Expand Down Expand Up @@ -920,6 +923,12 @@ input[type=file]
margin: 0
white-space: nowrap

ul.anim
visibility: visible
opacity: 1
transition: opacity .3s ease, transform .3s ease
transform: translate3d(0, 0, 0)

.css > li > ul
transition: opacity .15s ease

Expand Down

0 comments on commit 8c58b91

Please sign in to comment.