【问题标题】:jQuery animation with height jumps/shifts具有高度跳跃/移位的 jQuery 动画
【发布时间】:2012-03-19 06:15:56
【问题描述】:

我正在尝试编写一个可以从 DOM 中删除元素的函数,但是我遇到了一个我无法解决的问题。

代码如下所示:

function closeMessage(message) {
    var height = $(message).outerHeight();
    $(message).fadeTo("fast", 0.01).animate({marginTop: -height, marginBottom: 0}, function(){
        $(message).remove();
    });
}

变量message 是要移除的元素。在 CSS 中,我已将 margin-topmargin-bottom 分配给消息元素。

执行上述函数时,消息元素的不透明度降低到 0.01%(= 几乎不可见但仍然存在),然后负边距会产生消息元素下方的内容向上滑动的效果。之后在回调中,消息元素从 DOM 中移除。

问题是,messages-elements 下方的内容会像轻微的颠簸一样将最后几个像素跳到顶部。仅当存在多个消息框时,这种震动才明显。设置的边距越大,它也变得越明显。如您所见,我已尝试使用marginBottom: 0 解决问题,但它不起作用。

我还尝试了 jQuery 的不同 height(); 函数,例如 outerHeight();outherHeight(true);innerHeight();,但这并没有解决问题。

所以我的问题是:上面的代码有问题吗?为什么在动画的最后阶段会有那么小的“跳跃”?这是正常行为吗?

【问题讨论】:

  • 您能提供一个工作示例吗?我在一个只有两个 div 的简单页面上对其进行了测试。顶部的被移除,底部的向上移动,没有颠簸。
  • 我无法链接到真正的项目,因为它是内部的,但我已经构建了一个示例 here。尝试始终关闭底部的消息。如果你问我,动画不流畅。
  • 嗯,你的例子对我来说也很好,平滑,没有颠簸。我用的是Firefox 10.0.2,你用的是什么浏览器?
  • 我在 Safari 5.2.1、Firefox 9 和 Chrome 17 中尝试过。我更新了示例(更大的边距)以使问题更加清晰。试着关上黄色的盒子——灰色男孩跳了一下。 see here。只有当蓝色的盒子关闭时,它才能顺利运行。

标签: jquery jquery-animate height flicker


【解决方案1】:

jQuery animate 函数使用一个名为 swing 的默认缓动函数。尝试更改您的代码以使用“线性”缓动函数。

$(message).fadeTo("fast", 0.01).animate({marginTop: -height, marginBottom: 0},'linear', function(){
        $(message).remove();
    });

查看文档here

【讨论】:

  • 感谢您的回答,但恐怕没有解决问题。也许您可以查看上面发布的示例?
【解决方案2】:

第一个问题是outerHeight 不考虑边距而不将true 传递给它:

var height = $(message).outerHeight(true);
$(message).fadeTo("fast", 0.01).animate({marginTop: -height, marginBottom: 0}, function(){
    $(message).remove();
});

第二个问题是,根据 CSS 定义,相邻元素的垂直边距折叠,这意味着底部边距与下一个元素的顶部边距重叠。这使得计算更加困难,除非所有顶部/底部边距始终相同。

编辑:我认为只要你没有负边距或任何真正奇怪的东西,以下应该可以工作:

function closeMessage(message) {
    var pBot = 0;

    if ($(message).prev().length) {
        pBot = parseInt($(message).prev().css('marginBottom'));
    }

    var height = $(message).outerHeight();
    $(message).fadeTo("fast", 0.01).animate({
        marginTop: -height-pBot+'px',
        marginBottom: pBot+'px'
    }, 'linear', function() {
        $(message).remove();
    });
}

这使得正在消失的元素折叠其上边距,通过否定其上方元素的边距并通过减去它的高度(没有边距)使元素“消失”,同时设置它自己的底部-margin 与它上面的元素相同,基本上匹配它消失时将存在的元素。它似乎工作正常,您只需要担心上一个边距,因为下一个是自动处理的。

示例:http://jsfiddle.net/FxR9M/

我自己的例子有助于了解发生了什么:http://jsfiddle.net/5PRy2/2/

【讨论】:

  • 谢谢,这几乎解决了我的问题,see here。现在唯一的问题是,当关闭最后一个框时,灰色框滑到顶部太多了。我真的不明白为什么,因为灰色框声明了margin-top
  • 比这更复杂。计算的两个项目之间的边距是顶部元素的底部边距和底部元素的顶部边距的最大值​​。因此,您必须知道消失元素的计算顶部和底部边距,以及计算的上下元素之间的边距是多少。我正在想办法简化这个...
  • 我明白你在说什么。使用 jQuery 的 next();prev(); 函数获得这些边距是没有问题的。我只是现在没有把它放在一起。当只剩下一条消息时,我必须更改框向上移动的数量,但我就是无法正常工作。
  • 好的,我想出了一个似乎可行的解决方案。请参阅答案中的编辑。
  • 令人印象深刻,我只能这么说!哦,当然非常感谢你,在这里工作得很好。现在我有新的东西要学...也感谢“文档”和示例,干得好!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-07-08
  • 1970-01-01
  • 2011-10-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-21
相关资源
最近更新 更多