For*_*vin 11 html javascript jquery scroll smooth-scrolling
我想让页面慢慢平滑地向下滚动.那么,速度实际上应该是可调的.用户还应该能够在脚本向下滚动时手动向上滚动.首先我尝试了这个:
var autoScrollDelay = 1
var autoScrollSpeed = 1
var autoScrollTimer
function setAutoScroll(newValue) {
autoScrollSpeed = newValue ? newValue : autoScrollSpeed
if (autoScrollTimer) {
clearInterval(autoScrollTimer)
}
if (autoScrollDelay) {
autoScrollTimer = setInterval(function(){
window.scrollBy(0,autoScrollSpeed)
},autoScrollDelay)
}
}
setAutoScroll(1) // higher number = faster scrolling
Run Code Online (Sandbox Code Playgroud)
但它导致了非常繁重的CPU负载,而最慢的速度太快了.除此之外,在代码运行时手动向上滚动也无法正常工作.
然后我尝试了:
var autoScrollDelay = 1
var autoScrollSpeed = 1
var autoScrollTimer
function setAutoScroll(newValue) {
autoScrollDelay = newValue ? newValue : autoScrollDelay //using autoScrollDelay instead of autoScrollSpeed
if (autoScrollTimer) {
clearInterval(autoScrollTimer)
}
if (autoScrollDelay) {
autoScrollTimer = setInterval(function(){
window.scrollBy(0,autoScrollSpeed)
},autoScrollDelay)
}
}
setAutoScroll(200) // higher number scrolls slower
Run Code Online (Sandbox Code Playgroud)
但是当设置太慢时(例如200)滚动不顺畅.
然后我尝试了:
$("html, body").animate({
scrollTop: $('html, body').get(0).scrollHeight,
}, 40000, "linear");
Run Code Online (Sandbox Code Playgroud)
但是CPU负载再次过高并且手动向上或向下滚动这种方式是不可能的.
有一个更好的方法吗?
Con*_*Fan 13
这是一种可能的实现方式.刷新率是固定的,对应fps于下面的代码.为了确保速度恒定,我考虑计算新滚动位置后自上一次滚动以来经过的时间.手动滚动被允许(与滚动条,用鼠标滚轮,或与移动设备上的触摸),并通过处理考虑scroll,wheel和touchmove事件.您可以在此codepen中查看代码.
var fps = 100;
var speedFactor = 0.001;
var minDelta = 0.5;
var autoScrollSpeed = 10;
var autoScrollTimer, restartTimer;
var isScrolling = false;
var prevPos = 0, currentPos = 0;
var currentTime, prevTime, timeDiff;
window.addEventListener("scroll", function (e) {
// window.pageYOffset is the fallback value for IE
currentPos = window.scrollY || window.pageYOffset;
});
window.addEventListener("wheel", handleManualScroll);
window.addEventListener("touchmove", handleManualScroll);
function handleManualScroll() {
// window.pageYOffset is the fallback value for IE
currentPos = window.scrollY || window.pageYOffset;
clearInterval(autoScrollTimer);
if (restartTimer) {
clearTimeout(restartTimer);
}
restartTimer = setTimeout(() => {
prevTime = null;
setAutoScroll();
}, 50);
}
function setAutoScroll(newValue) {
if (newValue) {
autoScrollSpeed = speedFactor * newValue;
}
if (autoScrollTimer) {
clearInterval(autoScrollTimer);
}
autoScrollTimer = setInterval(function(){
currentTime = Date.now();
if (prevTime) {
if (!isScrolling) {
timeDiff = currentTime - prevTime;
currentPos += autoScrollSpeed * timeDiff;
if (Math.abs(currentPos - prevPos) >= minDelta) {
isScrolling = true;
window.scrollTo(0, currentPos);
isScrolling = false;
prevPos = currentPos;
prevTime = currentTime;
}
}
} else {
prevTime = currentTime;
}
}, 1000 / fps);
}
setAutoScroll(20);
Run Code Online (Sandbox Code Playgroud)
本文的功能使用vanilla JS以各种速度实现平滑滚动.这是一个演示:
document.getElementById("scrollBottomButton").onclick = function() {
var duration = document.getElementById("bottomScrollDuration").value * 1000;
scrollIt(document.querySelector("#bottom-row"), duration, "easeOutQuad");
};
document.getElementById("scrollTopButton").onclick = function() {
var duration = document.getElementById("topScrollDuration").value * 1000;
scrollIt(document.getElementById("top-row"), duration, "easeOutQuad");
};
// thanks to https://pawelgrzybek.com/page-scroll-in-vanilla-javascript/
function scrollIt(destination, duration = 200, easing = "linear", callback) {
const easings = {
linear(t) {
return t;
},
easeOutQuad(t) {
return t * (2 - t);
}
};
const start = window.pageYOffset;
const startTime = "now" in window.performance
? performance.now()
: new Date().getTime();
const documentHeight = Math.max(
document.body.scrollHeight,
document.body.offsetHeight,
document.documentElement.clientHeight,
document.documentElement.scrollHeight,
document.documentElement.offsetHeight
);
const windowHeight =
window.innerHeight ||
document.documentElement.clientHeight ||
document.getElementsByTagName("body")[0].clientHeight;
const destinationOffset = typeof destination === "number"
? destination
: destination.offsetTop;
const destinationOffsetToScroll = Math.round(
documentHeight - destinationOffset < windowHeight
? documentHeight - windowHeight
: destinationOffset
);
if ("requestAnimationFrame" in window === false) {
window.scroll(0, destinationOffsetToScroll);
if (callback) {
callback();
}
return;
}
function scroll() {
const now = "now" in window.performance
? performance.now()
: new Date().getTime();
const time = Math.min(1, (now - startTime) / duration);
const timeFunction = easings[easing](time);
window.scroll(
0,
Math.ceil(timeFunction * (destinationOffsetToScroll - start) + start)
);
if (window.pageYOffset === destinationOffsetToScroll) {
if (callback) {
callback();
}
return;
}
requestAnimationFrame(scroll);
}
scroll();
}
// scroll testing
var middleHtml = [];
const schiller = "Nur Beharrung führt zum Ziel, Nur die Fülle führt zur Klarheit, Und im Abgrund wohnt die Wahrheit.".split(' ')
for(var i=0; i<schiller.length;i+=1){
middleHtml.push("<div class=' container row' id='scrolling'><h1 style='margin: 30rem 10rem 30rem 0;font-size: 3.5em;font-family: Helvetica, sans-serif;color: #fff;'>"+schiller[i]+"</h1></div>");
}
document.getElementById('middle').innerHTML = middleHtml.join('');Run Code Online (Sandbox Code Playgroud)
.container-fluid {
background: #e52d27;
background: -webkit-linear-gradient(to top, #b31217, #e52d27);
background: linear-gradient(to top, #b31217, #e52d27);
}
.container-fluid input, .container-fluid .btn {
border-radius: 0;
}
.btn {
background: rgba(210,200,200,0.95);
}Run Code Online (Sandbox Code Playgroud)
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" rel="stylesheet"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" rel="stylesheet"/>
<div class='container-fluid'>
<div class='row' id='top-row'>
<div class='col-sm-8'>
<input class='form-control' id='bottomScrollDuration' placeholder='Enter duration in seconds (4, 25, 40, etc...)' />
</div>
<div class='col-sm-4'>
<button class='btn' id='scrollBottomButton'>Scroll to bottom</button>
</div>
</div>
<div id='middle'>
</div>
<div class='row' id='bottom-row'>
<div class='col-sm-8'>
<input class='form-control' id='topScrollDuration' placeholder='Enter duration in seconds (4, 25, 40, etc...)' />
</div>
<div class='col-sm-4'>
<button class='btn' id='scrollTopButton'>Scroll to top</button>
</div>
</div>
</div>Run Code Online (Sandbox Code Playgroud)
请参阅CodePen演示
更新
如果您只想调整速度并保持不变的滚动行为,可以试试这个:
function pageScroll(speed) {
window.scrollBy(0,1);
scrolldelay = setTimeout(pageScroll,speed);
}
Run Code Online (Sandbox Code Playgroud)
然后以您选择的速度调用该函数,即:
pageScroll(1);
Run Code Online (Sandbox Code Playgroud)
我在Chrome中运行它,并没有对我的CPU使用率征税.当它在Firefox中运行时,CPU会出现更多峰值.
| 归档时间: |
|
| 查看次数: |
6061 次 |
| 最近记录: |