子菜单动画“弹出”

时间:2013-12-05 19:31:20

标签: javascript jquery html css animation

我有一个包含子项目的菜单。为了制作我想要的动画效果,我需要检索子菜单宽度高度其第一个孩子的高度。现在我的动画有效,但有时我的子菜单只是“弹出”(它没有动画宽度)。

这是问题的 The Fiddle


http://www.vasinternetposao.com/wordpressdevelopment/wp-content/themes/override/images/submenu_problem.png

我正在使用此代码:

var j = jQuery.noConflict();
j(document).ready(function () {

    j('ul.nav').removeClass('nav').addClass('jnav'); //Add jquery Class to our menu 

    j('ul.jnav li').hover(function () {
        if (j(this).children('ul:first').hasClass('jsub-menu')) { //Let's check if "jsub-menu" Class is here
            return false; //If it is ("jsub-menu" here) don't SlideDown...
        } else { //Else slide down if no class
            j(this).find('ul.sub-menu:first').not(':animated').slideDown(500);
        }

    }, function () {
        j(this).find('ul:first').slideUp(500, function () {
            j(this).removeClass('jsub-menu').addClass('sub-menu');
            j(this).css({
                'height': '',
                'width': ''
            });
        });

    });

    j('ul.jnav ul.sub-menu a').hover(function () {
        j(this).addClass('active');

        if (j('.active').next('ul.sub-menu').length) { //If submenu exist...
            j('.active').next('ul.sub-menu').css({
                'visibility': 'hidden',
                'opacity': '0',
                'display': 'block'
            }); //Show it so we can read its:

            var get_width = j('.active').next('ul.sub-menu').outerWidth(true); //WIDTH
            var get_height_of_first_child = j('.active').next('ul.sub-menu').children('li:first').outerHeight(true); //HEIGHT of its First Child
            var get_submenu_height = j('.active').next('ul.sub-menu').outerHeight(true); //HEIGHT of our menu

            j('.active').next('ul').removeClass('sub-menu') //Remove class from menu, add another class apply HEIGHT of FIRST CHILD and hide it again...
            .addClass('jsub-menu').css({
                'visibility': '',
                'opacity': '',
                'height': get_height_of_first_child + 'px',
                'width': '0'
            });
            j('.active').next('.jsub-menu').animate({
                width: get_width
            }, 1000, function () { //Animate WIDTH

                j('.active').next('.jsub-menu').animate({
                    height: get_submenu_height
                }, 1000); //callback animate HEIGHT
            });
        } //End if    
    }, function () {
        j('.active').removeClass('active');
    });

});

我认为这是因为我的向上/向下动画与我的动画与/ height 功能相冲突但我不确定。我尝试通过在多种组合中添加stop()stop(true,true)stop(true,false)来解决此问题,但失败了。我现在试图解决这个问题,所以堆叠器是我唯一的希望。请帮忙!
谢谢!

1 个答案:

答案 0 :(得分:2)

我终于能够复制错误了。

我为您编写了此代码,以替换您为动画创建的代码。

var animating = false;
function animate($elm, options, callback) {        
    if (animating) 
        return;

    animating = true;
    $elm.animate(options, 1000, function() {
        animating = false;

        if (callback != undefined)
            callback();
    });        
}

从你的悬停回调中调用它。

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

基本上,它会检查另一个动画是否已经在运行,在这种情况下它不会启动它。动画停止时,Flag设置为false,让其他动画继续播放。

您还可以在动画完成后传递回调以执行某些操作,但在您的情况下您不需要它,因为您可以在同一时间设置高度和宽度的动画。

我测试了一分钟,看起来很顺利。

以下是更新后的Feed:http://jsfiddle.net/gabrielcatalin/TNxJ4/1/

P.S。您可能还想对jQuery包装器使用$符号而不是'j'。