【问题标题】:jQuery Animation runs pporly on first eventjQuery Animation 在第一个事件上运行不佳
【发布时间】:2013-03-24 11:31:48
【问题描述】:

我一直在用 jQuery 构建一些选项卡,除了选项卡容器大小的动画不一致,第一次运行时它有点跳动并且时间关闭之外,它们的效果非常好。

当单击一个选项卡触发器时,它应该淡出当前选项卡,.show 新的 contnet(不透明度设置为 0,以便我可以得到准确的高度) - 调整容器高度并淡入活动的不透明度标签。

它可以工作,但是在第一次单击任何选项卡时会出现问题,一旦您再次单击选项卡,它就会完美运行 - 我做错了什么?

在这里查看 jsfiddle 以获得完整的代码和演示......http://jsfiddle.net/pushplaybang/rjS2B/

我的脚本如下所示:

var tabs = {

trig   : $('nav.tab-triggers'),
content: $('section.tabs-content'),
panels : $('section.tabs-content').children(),

// Kick off
init   : function() {
    $.each(tabs.content,function(index, value) {
         $(value).children(':first').addClass('active').show().children().css('opacity', '1');
        $(value).children().not(':first').children('opacity', '0').end().hide();
    });
    tabs.address([tabs.trig]);
    tabs.address([tabs.content]);
    tabs.trig.on('click', 'a', tabs.display);
},

// assign incremental classes hrefs and id's to containers (grouped by class), triggers, and panels
address: function(obj) {
    // for each obj
    $.each(obj, function(index,value) {
         $.each(obj[index], function(index2,value2) {
            $(value2).addClass('tabs-' + index2);
            var kids = $(value2).children();
            $.each(kids, function(index3, value3) {
                var kid = $(value3);
                // if its parent is a nav element
                if ( kid.parent().is('nav') ) {
                // add href
                    kid.attr('href', '#tab-' + index3);
                } else {
                // add matching ids
                    kid.attr('id', 'tab-' + index3);
                }
            });  // end loop through children elements
        }); // end loop through parent elements
    }); // iteration of passed obj
}, // end address method

display: function (e) {
    var clicked = $(this);
    var link    = clicked.attr('href');
    var target  = clicked.parent().next().children(link);
    var active = clicked.parent().next().children('.active');

    clicked.addClass('active').siblings().removeClass('active');

    active.children().animate({
        opacity : 0
    },180, function() {
        active.removeClass('active').fadeOut(20, function() {
            target.addClass('active').show(0, function() {
                var tabheight = target.outerHeight();
                target.parent().animate({
                    height: tabheight + 40
                },200, function() {
                    target.children().animate({
                        opacity : 1
                    });
                });
            });
        });
    });
    e.preventDefault();
} // end display method

}

tabs.init();

这是一个微妙的错误,但很烦人。

【问题讨论】:

    标签: jquery


    【解决方案1】:

    你的错误的原因:

    • 在活动标签fadeOut的完整回调中:
      • 你直接调用target.addClass('active').show但是它的children'opacity没有设置为0,导致他们的延迟不透明度动画从当前不透明度到1第一次没有做任何事情
      • => 你可以插入这些链式调用 target.children().css({opacity: 0}).end().addClass('active').show .children().css({opacity: 0}).end() 只是去儿童并改变他们的不透明度。

    你不应该做的事情(为了性能和清晰度):

    • 你调用 show 时延迟为 0,这太糟糕了,因为它会在你想要立即获得结果的地方创建一个动画(是吗?也许 jQuery 1.9 现在做得更好?)
    • 您每次都检索活动选项卡。一个简单的闭包变量可以引用最后一个活动选项卡
    • 您不会将您显示的动画与活动动画进行比较,因此尝试显示活动动画会重新启动动画
    • 不停止当前动画,导致多次点击排队动画

    您可能会在这里查看幻灯片切换实现: http://jsfiddle.net/alexis_tondelier/Gf2dv/ 它会停止动画,引用活动项目,测试它是否相同并在这种情况下关闭它,并且还会在您单击外部时收听要关闭的内容(实际上这并不完全是您的情况)。

    【讨论】:

    • 嘿,感谢您提供全面的答案,不过我想更好地理解一些事情,以您建议的方式更改目标链调用修复了动画错误(尽管我认为设置它在我的 init 方法中已将所有子项的不透明度设置为 0?)我将其全部包裹在 if !hasClass active 中以避免重新启动动画。
    • 很抱歉现在才看到这个,但当然最好在 init 调用中应用它。在那里,您使用参数 opacity 和 0 调用方法 children,其中使用 css 方法将是更好的选择。 :-)
    • 进一步 - 我使用 .show 真的是一种廉价的方式来获取回调,因为我想在基本上将选项卡设置为活动以阻止之前执行所有其他操作,然后检索其高度以调整容器和然后显示内容。关于关闭,我不是 100% 确定 - 如何以及为什么 - 我已经阅读了解释并倾注了博客试图理解它,但如果你能解释你在这种情况下的意思,那将非常有帮助。谢谢。
    • 刚刚意识到我在 init 语法中犯了一个多么愚蠢的错误 - 我也更正了这个错误 - 但我真的对你谈到的性能技巧很感兴趣
    • 我已经更新了 JS 小提琴,但任何其他信息都会很棒
    猜你喜欢
    • 1970-01-01
    • 2018-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多