ページをゆっくりとスムーズにスクロールさせたい。まあ、速度は実際に調整可能でなければなりません。スクリプトが下にスクロールしている間、ユーザーは手動で上にスクロールできる必要もあります。まず私はこれを試しました:
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
しかし、それは非常に重い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
ただし、設定が遅すぎるとスクロールがスムーズになりませんでした(例:200)。
それから私は試しました:
$("html, body").animate({
scrollTop: $('html, body').get(0).scrollHeight,
}, 40000, "linear");
ただし、CPUの負荷が非常に高く、手動で上下にスクロールすることはできませんでした。
これを行うより良い方法はありますか?
これが可能な実装の1つです。リフレッシュレートは固定されており、以下のコードのfps
に対応しています。速度が一定であることを確認するために、新しいスクロール位置を計算するときに、前回のスクロールからの経過時間を考慮します。手動スクロールは許可され(スクロールバー、マウスホイール、またはモバイルデバイスのタッチ)、scroll
、wheel
、およびtouchmove
イベントを処理することで考慮されます。 this 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);
この記事 の関数は、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('');
.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);
}
<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>
CodePen Demoを参照してください
更新
速度を調整して一定のスクロール動作を維持したい場合は、これを試すことができます。
function pageScroll(speed) {
window.scrollBy(0,1);
scrolldelay = setTimeout(pageScroll,speed);
}
次に、選択した速度で関数を呼び出します。
pageScroll(1);
私はそれをChromeで実行しましたが、CPU使用量に負担をかけることはありませんでした。 Firefoxで実行すると、CPUのスパイクが大きくなります。