如何为我的菜单创建流畅的动画?

3
我有一个菜单,在“悬停”时会展开,但问题是,如果我悬停在一个项目上,并且该项目正在运行动画,则下一个项目的动画将不会很流畅(基本上子菜单将在动画中间显示)。
我已经创建了JS Fiddle来展示这个问题。
我认为我的代码中的这部分引起了问题:
j('.active').next('ul')
.removeClass('sub-menu')
.addClass('jsub-menu').css({
'visibility':'',
'opacity':'',
'height':get_height_of_first_child +'px',
'width':'0'
 });
j('.active').next('.jsub-menu').animate({width:get_width},2000);

j('.active').next('.jsub-menu').animate({height:get_submenu_height},2000);

编辑:这是更新的Fiddle Code。如果你仔细看第59行,我加入了这段代码:

if(j('.active').next('.jsub-menu').is(':animated')){ j('.active').next('.jsub-menu').hide(); }

现在,如果你悬停在一个"Hover me while I am expanding!"菜单上,并且该菜单正在动画过程中,它将隐藏菜单(虽然我不希望出现这种情况,但请耐心等待)。

现在,请尝试悬停在一个"Hover me"上,等待4-5秒钟,然后再悬停在"Hover me while I am expanding!"上,你会发现下一个菜单平滑地动画了。

这就是我想要的效果,但显然我不想在此过程中隐藏菜单。


1
你想要看到什么结果?如果正在运行动画的项目仍在运行,你想要等待该动画完成后再开始下一个动画,还是希望下一个动画在前一个动画尚未完成时就开始显示? - John T
是的,我想在第一个动画完成后开始第二个动画... - Dejo Dekic
我建议(如果可能的话)重新设计导航,因为太多级别会很烦人,而且还会遇到意外的鼠标移出问题,然后用户就必须重新开始。我建议跳转到UX Stack Exchange(http://ux.stackexchange.com/)寻找一些简化菜单、提高用户体验的方法。 - Don
1个回答

4

以下是我的做法。它会检查是否为父级.jnav的直接子菜单,如果是,则使用slideDown。否则,在元素具有visibility:hidden时获取其宽度,并将其动画化到该宽度。

var j = jQuery.noConflict();    
j(document).ready(function () {    
    j('ul.nav').removeClass('nav').addClass('jnav');    
    j('ul.jnav li').hover(function () {
        if (j(this).children('ul:first').hasClass('jsub-menu')) { 
            return false; 
        } else {    
            if(j('ul.jnav > li').is(this)) {
                j(this).find('ul.sub-menu:first').not(':animated').slideDown(500);
            } else {
                var elem = j(this).find('ul.sub-menu:first').not(':animated');
                elem.css({
                    visibility: 'hidden',
                    display: 'block'                    
                });
                var elemWidth = elem.width();
                console.log(elemWidth);
                elem.css({
                    width: '0px',
                    visibility: 'visible'
                }).animate({
                    width: elemWidth
                });
            }
        }
    }, function () {
        j(this).find('ul:first').slideUp(500, function () {
            j(this).removeClass('jsub-menu').addClass('sub-menu');            
        });
    });    
});

Updated jsFiddle


是的,这个方法可以实现,但是你可能已经注意到了,在我的例子中,我只想让第一个子菜单下拉,其他所有子菜单都必须动态调整宽度,然后检查是否有子元素并动态调整高度。 - Dejo Dekic
@DejoDekic 已更新以解决该问题。 - Zach Saucier
不用担心 :) 我会接受你的答案,但我需要等待20个小时才能授予你赏金;) - Dejo Dekic
@DejoDekic 没有必要这样做!我对自己拥有的一切感到非常满意! - Zach Saucier
这就是你想要的;) 我没有立即授予你奖励,因为我想看看更多的答案或建议... 无论如何,感谢@Zack的帮助和出色的编码。 - Dejo Dekic

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接