Javascript 是否可以使用 jQuery 为 scrollTop 设置动画?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4034659/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 07:13:21  来源:igfitidea点击:

Is it possible to animate scrollTop with jQuery?

javascriptjquery

提问by Bryan Field

I want to smoothly scroll down. I do not want to have to write a function for that - especially if jQuery already has one.

我想顺利向下滚动。我不想为此编写一个函数 - 特别是如果 jQuery 已经有了一个。

回答by Nick Craver

You can just use .animate()the scrollTopproperty, like this:

您可以只使用.animate()scrollTop属性,如下所示:

$("html, body").animate({ scrollTop: "300px" });

回答by Kita

Nick's answer works great. Be careful when specifying a complete() function inside the animate() call because it will get executed twice since you have two selectors declared (html and body).

尼克的回答很有效。在 animate() 调用中指定 complete() 函数时要小心,因为它会被执行两次,因为你声明了两个选择器(html 和 body)。

$("html, body").animate(
    { scrollTop: "300px" },
    {
        complete : function(){
            alert('this alert will popup twice');
        }
    }
);

Here's how you can avoid the double callback.

以下是避免双重回调的方法。

var completeCalled = false;
$("html, body").animate(
    { scrollTop: "300px" },
    {
        complete : function(){
            if(!completeCalled){
                completeCalled = true;
                alert('this alert will popup once');
            }
        }
    }
);

回答by pathfinder

Nick's answer works great and the default settings are nice, but you can more fully control the scrolling by completing all of the optional settings.

Nick 的回答效果很好,默认设置也很好,但是您可以通过完成所有可选设置来更全面地控制滚动。

here is what it looks like in the API:

这是它在 API 中的样子:

.animate( properties [, duration] [, easing] [, complete] )

so you could do something like this:

所以你可以做这样的事情:

.animate( 
    {scrollTop:'300px'},
    300,
    swing,
    function(){ 
       alert(animation complete! - your custom code here!); 
       } 
    )

here is the jQuery .animate function api page: http://api.jquery.com/animate/

这是 jQuery .animate 函数 api 页面:http://api.jquery.com/animate/

回答by Stephen

Like Kita mentioned there is a problem with multiple callbacks firing when you animate on both 'html' and 'body'. Instead of animating both and blocking subsequent callbacks I prefer to use some basic feature detection and only animate the scrollTop property of a single object.

就像 Kita 提到的那样,当您在 'html' 和 'body' 上设置动画时,会触发多个回调。我更喜欢使用一些基本的特征检测并且只为单个对象的 scrollTop 属性设置动画,而不是同时设置动画和阻止后续回调。

The accepted answer on this other thread gives some insight as to which object's scrollTop property we should try to animate: pageYOffset Scrolling and Animation in IE8

在另一个线程上接受的答案提供了一些关于我们应该尝试动画的对象的 scrollTop 属性的见解:pageYOffset Scrolling and Animation in IE8

// UPDATE: don't use this... see below
// only use 'body' for IE8 and below
var scrollTopElement = (window.pageYOffset != null) ? 'html' : 'body';

// only animate on one element so our callback only fires once!
$(scrollTopElement).animate({ 
        scrollTop: '400px' // vertical position on the page
    },
    500, // the duration of the animation 
    function() {       
        // callback goes here...
    })
});

UPDATE - - -

更新 - - -

The above attempt at feature detection fails. Seems like there's not a one-line way of doing it as webkit type browsers pageYOffset property always returns zero when there's a doctype. Instead, I found a way to use a promise to do a single callback for every time the animation executes.

上述特征检测尝试失败。似乎没有一种单行的方式来做到这一点,因为当有文档类型时,webkit 类型浏览器的 pageYOffset 属性总是返回零。相反,我找到了一种方法,可以在每次动画执行时使用 promise 进行单个回调。

$('html, body')
    .animate({ scrollTop: 100 })
    .promise()
    .then(function(){
        // callback code here
    })
});

回答by John Starr Dewar

I have what I believe is a better solution than the $('html, body')hack.

我有我认为比$('html, body')黑客更好的解决方案。

It's not a one-liner, but the issue I had with $('html, body')is that if you log $(window).scrollTop()during the animation, you'll see that the value jumps all over the place, sometimes by hundreds of pixels (though I don't see anything like that happening visually). I needed the value to be predictable, so that I could cancel the animation if the user grabbed the scroll bar or twirled the mousewheel during the auto-scroll.

这不是单行的,但我遇到的问题$('html, body')是,如果您$(window).scrollTop()在动画期间登录,您会看到该值到处跳跃,有时跳动数百个像素(尽管我没有看到类似的东西)视觉上发生)。我需要该值是可预测的,以便在用户在自动滚动期间抓住滚动条或转动鼠标滚轮时我可以取消动画。

Here is a function will animate scrolling smoothly:

这是一个可以平滑滚动动画的函数:

function animateScrollTop(target, duration) {
    duration = duration || 16;
    var scrollTopProxy = { value: $(window).scrollTop() };
    if (scrollTopProxy.value != target) {
        $(scrollTopProxy).animate(
            { value: target }, 
            { duration: duration, step: function (stepValue) {
                var rounded = Math.round(stepValue);
                $(window).scrollTop(rounded);
            }
        });
    }
}

Below is a more complex version that will cancel the animation on user interaction, as well as refiring until the target value is reached, which is useful when trying to set the scrollTop instantaneously (e.g. simply calling $(window).scrollTop(1000)— in my experience, this fails to work about 50% of the time.)

下面是一个更复杂的版本,它将取消用户交互时的动画,并重新触发直到达到目标值,这在尝试立即设置 scrollTop 时很有用(例如,简单地调用$(window).scrollTop(1000)- 根据我的经验,这无法正常工作50% 的时间。)

function animateScrollTop(target, duration) {
    duration = duration || 16;

    var $window = $(window);
    var scrollTopProxy = { value: $window.scrollTop() };
    var expectedScrollTop = scrollTopProxy.value;

    if (scrollTopProxy.value != target) {
        $(scrollTopProxy).animate(
            { value: target },
            {
                duration: duration,

                step: function (stepValue) {
                    var roundedValue = Math.round(stepValue);
                    if ($window.scrollTop() !== expectedScrollTop) {
                        // The user has tried to scroll the page
                        $(scrollTopProxy).stop();
                    }
                    $window.scrollTop(roundedValue);
                    expectedScrollTop = roundedValue;
                },

                complete: function () {
                    if ($window.scrollTop() != target) {
                        setTimeout(function () {
                            animateScrollTop(target);
                        }, 16);
                    }
                }
            }
        );
    }
}

回答by complistic

I was having issues where the animation was always starting from the top of the page after a page refresh in the other examples.

我遇到的问题是,在其他示例中刷新页面后,动画总是从页面顶部开始。

I fixed this by not animating the css directly but rather calling window.scrollTo();on each step:

我通过不直接为 css 设置动画而是调用window.scrollTo();每个步骤来解决此问题:

$({myScrollTop:window.pageYOffset}).animate({myScrollTop:300}, {
  duration: 600,
  easing: 'swing',
  step: function(val) {
    window.scrollTo(0, val);
  }
});

This also gets around the htmlvs bodyissue as it's using cross-browser JavaScript.

这也解决了htmlvsbody问题,因为它使用跨浏览器 JavaScript。

Have a look at http://james.padolsey.com/javascript/fun-with-jquerys-animate/for more information on what you can do with jQuery's animate function.

查看http://james.padolsey.com/javascript/fun-with-jquerys-animate/以了解有关使用 jQuery 的 animate 函数可以做什么的更多信息。

回答by Alessandro Pirovano

You can use the jQuery animation for scroll page with a specific duration:

您可以将 jQuery 动画用于具有特定持续时间的滚动页面:

$("html, body").animate({scrollTop: "1024px"}, 5000);

where 1024px is the scroll offset and 5000 is the duration of animations in millisecond.

其中 1024px 是滚动偏移量,5000 是动画的持续时间(以毫秒为单位)。

回答by Tatu Ulmanen

Try the scrollToplugin.

试试 scrollTo插件。

回答by Rubel Hossain

$(".scroll-top").on("click", function(e){
   e.preventDefault();
   $("html, body").animate({scrollTop:"0"},600);
});

回答by Small Ant

If you want to move down at the end of the page (so you don't need to scroll down to bottom) , you can use:

如果您想在页面末尾向下移动(这样您就不需要向下滚动到底部),您可以使用:

$('body').animate({ scrollTop: $(document).height() });