У меня есть то, что я считаю лучшим решением, чем взлом $('html, body')
.
Это не однострочный текст, но проблема, с которой я столкнулся с $('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);
}
}
}
);
}
}