【发布时间】:2021-07-05 02:25:19
【问题描述】:
我想流畅地向下滚动。我不想为此编写一个函数 - 特别是如果 jQuery 已经有一个。
【问题讨论】:
标签: javascript jquery
我想流畅地向下滚动。我不想为此编写一个函数 - 特别是如果 jQuery 已经有一个。
【问题讨论】:
标签: javascript jquery
您可以只使用.animate() scrollTop 属性,如下所示:
$("html, body").animate({ scrollTop: "300px" });
【讨论】:
html 和body?这里有一些见解:stackoverflow.com/questions/2123690/…,但这不是一个完整的答案。
<html> 具有overflow-x:hidden;,则此动画将不起作用。 (可能不适用于overflow-y:hidden 和overflow:hidden,但我没有测试过。
body 今年早些时候在 Chrome 中工作,但现在它必须是 html。
尼克的回答效果很好。在 animate() 调用中指定 complete() 函数时要小心,因为它会被执行两次,因为您声明了两个选择器(html 和 body)。
$("html, body").animate(
{ scrollTop: "300px" },
{
complete : function(){
alert('this alert will popup twice');
}
}
);
以下是避免双重回调的方法。
var completeCalled = false;
$("html, body").animate(
{ scrollTop: "300px" },
{
complete : function(){
if(!completeCalled){
completeCalled = true;
alert('this alert will popup once');
}
}
}
);
【讨论】:
live() 函数调用之前使用 die() 函数。这保证了您的 live() 处理程序只会被调用一次。
Nick 的回答效果很好,默认设置也不错,但是您可以通过完成所有可选设置来更全面地控制滚动。
这是它在 API 中的样子:
.animate( properties [, duration] [, easing] [, complete] )
所以你可以这样做:
.animate(
{scrollTop:'300px'},
300,
swing,
function(){
alert(animation complete! - your custom code here!);
}
)
这里是 jQuery .animate 函数 api 页面:http://api.jquery.com/animate/
【讨论】:
就像 Kita 提到的那样,当您在“html”和“body”上制作动画时,会触发多个回调。我更喜欢使用一些基本的特征检测并且只为单个对象的 scrollTop 属性设置动画,而不是同时设置动画并阻止后续回调。
在另一个线程上接受的答案提供了一些关于我们应该尝试为哪个对象的 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...
})
});
更新 - - -
上述特征检测尝试失败。似乎没有一种单行的方式来做到这一点,因为 webkit 类型的浏览器 pageYOffset 属性在有 doctype 时总是返回零。 相反,我找到了一种方法,可以在每次动画执行时使用 Promise 进行一次回调。
$('html, body')
.animate({ scrollTop: 100 })
.promise()
.then(function(){
// callback code here
})
});
【讨论】:
我认为比$('html, body') hack 更好的解决方案。
这不是单行的,但我对$('html, body') 的问题是,如果您在动画期间记录$(window).scrollTop(),您会看到该值在整个地方跳跃,有时跳跃数百像素(虽然我在视觉上看不到类似的事情发生)。我需要该值是可预测的,这样如果用户在自动滚动期间抓住滚动条或旋转鼠标滚轮,我就可以取消动画。
这是一个可以平滑滚动的函数:
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);
}
});
}
}
下面是一个更复杂的版本,它将在用户交互时取消动画,并重新触发直到达到目标值,这在尝试立即设置 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);
}
}
}
);
}
}
【讨论】:
在其他示例中,我遇到了在页面刷新后动画总是从页面顶部开始的问题。
我通过不直接为 css 设置动画来解决此问题,而是在每个步骤中调用 window.scrollTo();:
$({myScrollTop:window.pageYOffset}).animate({myScrollTop:300}, {
duration: 600,
easing: 'swing',
step: function(val) {
window.scrollTo(0, val);
}
});
这也解决了 html 与 body 的问题,因为它使用的是跨浏览器 JavaScript。
请查看http://james.padolsey.com/javascript/fun-with-jquerys-animate/,了解有关您可以使用 jQuery 的动画功能做什么的更多信息。
【讨论】:
您可以将 jQuery 动画用于具有特定持续时间的滚动页面:
$("html, body").animate({scrollTop: "1024px"}, 5000);
其中 1024px 是滚动偏移量,5000 是动画的持续时间(以毫秒为单位)。
【讨论】:
$("html, body").animate({scrollTop: 1024}, 5000); 也可以。
试试scrollTo 插件。
【讨论】:
$(".scroll-top").on("click", function(e){
e.preventDefault();
$("html, body").animate({scrollTop:"0"},600);
});
【讨论】:
如果你想在页面末尾向下移动(这样你就不需要向下滚动到底部),你可以使用:
$('body').animate({ scrollTop: $(document).height() });
【讨论】:
但如果你真的想在滚动时添加一些动画,你可以试试我的简单插件 (AnimateScroll),它目前支持 30 多种缓动样式
【讨论】:
跨浏览器代码为:
$(window).scrollTop(300);
它没有动画,但无处不在
【讨论】: