使用CSS3实现滚动动画

19

有没有一种使用CSS3实现滚动动画的方法?

像这样的效果?

@-webkit-keyframes scrolltoview
{
    0%   { scrollTop: 0; }
    100% { scrollTop: 30%; }
}

如何在CSS中指定动画的起始点?


不行,因为在CSS中甚至没有滚动无动画的选项。 - noob
你能澄清一下你所说的“动画滚动”是什么意思吗?滚动虽然平凡,但也是一种动画形式。你如何进一步地为它添加动画效果呢? - Anthony
@Micha 你说得对,即使没有动画我也做不了。 - Spiff
@Anthony 假设你现在在一个TextArea的最上方,你想要将其(在你的代码中)滚动到底部。如果没有动画,它会直接跳到底部。使用动画会使过程更加平滑。以iPhone为例思考。 - Spiff
5个回答

15

此处所解释的那样,您可以使用margin-top技巧并动态更新滚动位置来实现这一点。您可以查看演示。代码很简单:

// Define the variables
var easing, e, pos;
$(function(){
  // Get the click event
  $("#go-top").on("click", function(){
    // Get the scroll pos
    pos= $(window).scrollTop();
    // Set the body top margin
    $("body").css({
      "margin-top": -pos+"px",
      "overflow-y": "scroll", // This property is posed for fix the blink of the window width change 
    });
    // Make the scroll handle on the position 0
    $(window).scrollTop(0);
    // Add the transition property to the body element
    $("body").css("transition", "all 1s ease");
    // Apply the scroll effects
    $("body").css("margin-top", "0");
    // Wait until the transition end
    $("body").on("webkitTransitionEnd transitionend msTransitionEnd oTransitionEnd", function(){
      // Remove the transition property
      $("body").css("transition", "none");
    });
  });
});

@AndrewP 提供了一个基于这个想法的不错的工作示例


有没有一种好的方法可以使用锚点哈希(如#home或#services)来应用相同的效果? - Gerben van Dijk
2
@GerbenVanDijk 我迟了很久才做出来,但我已经构建了我认为你要求的东西(一个函数,用于查找页面上所有指向锚点的链接,并通过CSS3 + margin-top修改它们的点击以进行滚动,测试到IE 8):http://codepen.io/acusti/pen/bFBDr - Andrew Patton
抱歉 @AndrewP,它在 Safari 7.0 上不起作用。它可以滚动,但没有动画效果。 - mente
@mente 当我在修改或调整它时,你可能会发现它处于尴尬的破碎状态。我刚刚在Safari 7.0(9537.71)中再次检查了它,以验证它可以平稳地滚动。 - Andrew Patton
@mente 观察得非常敏锐!奇怪的是,在编辑CodePen视图中,它对我起作用,但单独使用时却出现了问题。我已经进行了调试和修复(希望如此)一劳永逸地解决了这个问题。我试图在documentElement上使用scrollTop,但在Safari中失败了,尽管它应该是标准方法。最终通过https://dev59.com/k2435IYBdhLWcg3whQY5#YqSeEYcBWogLw_1bWgYG找到了一个在Safari、Chrome、Firefox甚至IE 8(http://cdpn.io/bFBDr)中都有效的解决方案。 - Andrew Patton
@AndrewP - 我也晚了很多,但还是谢谢。现在在另一个项目中使用它! - Gerben van Dijk

9

CSS3动画只与CSS属性一起工作。这在CSS的限制范围内是不可能的。


4
我发现了一种更好的滚动动画方式,即使用JavaScript来转换文档主体。使用translate而不是margin或position进行动画的优势已经得到了很好的记录。归根结底,当动画元素时,GPU总是会做得更好。
以下是一个例子,它计算用户当前位置距离窗口顶部的距离,然后平滑地向上移动到窗口顶部。假设用户点击或触摸事件触发了backToTop函数。
在这里查看实际效果:https://antibland.github.io/starting_point/
function whichTransitionEvent() {
  var t,
      el          = document.createElement('fakeelement'),
      transitions = {
        'transition':'transitionend',
        'OTransition':'oTransitionEnd',
        'MozTransition':'transitionend',
        'WebkitTransition':'webkitTransitionEnd'
     };

  for (t in transitions){
    if (el.style[t] !== undefined){
      return transitions[t];
    }
  }
}

function backToTop() {
  var pos_from_top  = window.scrollY,
      transitionend = whichTransitionEvent(),
      body          = document.querySelector("body");

  function scrollEndHandler() {
    window.scrollTo(0, 0);
    body.removeAttribute("style");
    body.removeEventListener(transitionend, scrollEndHandler);
  }

  body.style.overflowY = "scroll";
  window.scrollTop = 0;

  body.style.webkitTransition = 'all .5s ease';
  body.style.transition = 'all .5s ease';

  body.style.webkitTransform = "translateY(" + pos_from_top + "px)";
  body.style.transform = "translateY(" + pos_from_top + "px)";

  transitionend && body.addEventListener(transitionend, scrollEndHandler);
}

不要被点赞搞混了,使用transform而不是margin-top可以显著提高性能! - Adi Darachi

0

这是我制作的一个非常简单的 .js 函数,用于动画和滚动网页。

var Current_scroll_Y=0;
var Target_scroll_Y=0;
var scroll_Speed = 15;

function animate_Scroll(Y)
{
  Target_scroll_Y = Y;
  screen_Y = Math.floor(window.scrollY);

  //Scroll Down
  if(screen_Y<Y)
  {
    var myWindowScroll = setInterval(function(){ screen_Y = screen_Y+scroll_Speed;  if(screen_Y>=Target_scroll_Y){ clearInterval(myWindowScroll); return;}    window.scrollTo(0, screen_Y); }, 3);   
  }
  //Scroll Up
  if(screen_Y>Y)
  {
    var myWindowScroll = setInterval(function(){ screen_Y = screen_Y-scroll_Speed;  if(screen_Y<=Target_scroll_Y){ clearInterval(myWindowScroll); return;}    window.scrollTo(0, screen_Y); }, 3);  
  } 


}//End animate_Scroll  

0

1
谢谢你的回答。我知道可以用 JQuery 来实现。 - Spiff

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