概要: このチュートリアルでは、JavaScriptスクロールイベントとその適切な処理方法について学習します。
JavaScriptスクロールイベントの紹介
ドキュメントまたは要素をスクロールすると、ブラウザはスクロールイベントを発生させます。スクロールイベントは次の方法でトリガーできます。
- スクロールバーの手動使用
- マウスホイール
- IDリンクのクリック
- JavaScriptでの関数の呼び出し
- など。
scrollイベントハンドラを登録するには、対象要素でaddEventListener()メソッドを呼び出します。
targetElement.addEventListener('scroll', (event) => {
// handle the scroll event
});Code language: PHP (php)または、対象要素のonscrollプロパティにイベントハンドラを割り当てます。
targetElement.onscroll = (event) => {
// handle the scroll event
};Code language: JavaScript (javascript)ドキュメントのスクロール
通常、ページ全体のスクロールを処理するために、windowオブジェクトにscrollイベントのイベントハンドラを登録します。
たとえば、次の例は、ページのscrollイベントにイベントハンドラをアタッチする方法を示しています。
window.addEventListener('scroll',(event) => {
console.log('Scrolling...');
});Code language: JavaScript (javascript)あるいは、windowオブジェクトのonscrollプロパティを使用することもできます。
window.onscroll = function(event) {
//
};Code language: JavaScript (javascript)windowオブジェクトのonscrollプロパティはdocument.body.onscrollと同じであり、互換性があります。
document.body.onscroll = null;
console.log(window.onscroll); // nullCode language: JavaScript (javascript)スクロールオフセット
windowオブジェクトには、スクロールイベントに関連する2つのプロパティがあります: scrollXとscrollY。
scrollXとscrollYプロパティは、ドキュメントが現在水平方向と垂直方向にスクロールされたピクセル数を返します。scrollXとscrollYは倍精度浮動小数点値なので、整数値が必要な場合は、Math.round()を使用して丸めることができます。
ドキュメントがまったくスクロールされていない場合、scrollXとscrollYは0になります。
pageXOffsetとpageYOffsetは、scrollXとscrollYプロパティのエイリアスです。
要素のスクロール
windowオブジェクトと同様に、scrollイベントハンドラを任意のHTML要素にアタッチできます。ただし、スクロールオフセットを追跡するには、scrollXとscrollYの代わりにscrollTopとscrollLeftを使用します。
scrollTopプロパティは、要素のコンテンツが垂直方向にスクロールされたピクセル数を設定または取得します。scrollLeftプロパティは、要素のコンテンツが左端からスクロールされたピクセル数を取得および設定します。
次の例は、idがscrollDemoのdiv要素のscrollイベントを処理する方法を示しています。
<!DOCTYPE html>
<html>
<head>
<title>JS Scroll Events</title>
<style>
#scrollDemo {
height: 200px;
width: 200px;
overflow: auto;
background-color: #f0db4f
}
#scrollDemo p {
/* show the scrollbar */
height: 300px;
width: 300px;
}
</style>
</head>
<body>
<div id="scrollDemo">
<p>JS Scroll Event Demo</p>
</div>
<div id="control">
<button id="btnScrollLeft">Scroll Left</button>
<button id="btnScrollTop">Scroll Top</button>
</div>
<script>
let control = document.querySelector('#control');
control.addEventListener('click', function (e) {
// get the scrollDemo
let div = document.getElementById('scrollDemo');
// get the target
let target = e.target;
// handle each button's click
switch (target.id) {
case 'btnScrollLeft':
div.scrollLeft += 20;
break;
case 'btnScrollTop':
div.scrollTop += 20;
break;
}
});
</script>
</body>
</html>
Code language: HTML, XML (xml)スクロールイベントを処理するより良い方法
ページまたは要素をスクロールしている間、多くのscrollイベントが発生します。scrollイベントにイベントリスナーをアタッチすると、イベントハンドラのコードの実行に時間がかかります。
これは、スクロールジャンクとして知られる問題を引き起こします。スクロールジャンク効果は遅延を引き起こし、ページが指に固定されていないように感じさせます。
イベントスロットリング
タイマーを使用して、scrollイベントハンドラを軽量に保ち、Nミリ秒ごとに実行する方がはるかに優れています。そのため、次のコード(決して使用しないでください)を使用する代わりに
window.scroll = () => {
// place the scroll handling logic here
};
Code language: JavaScript (javascript)次のコードを使用する必要があります。
let scrolling = false;
window.scroll = () => {
scrolling = true;
};
setInterval(() => {
if (scrolling) {
scrolling = false;
// place the scroll handling logic here
}
},300);
Code language: JavaScript (javascript)動作方法
- まず、
scrollingフラグをfalseに設定します。scrollイベントが発生した場合、scrollイベントハンドラ内でscrollingフラグをtrueに設定します。 - 次に、
scrollイベントが発生した場合は、300ミリ秒ごとにsetInterval()を使用してscrollイベントハンドラを実行します。
このscrollイベントの処理方法は、イベントスロットリングと呼ばれ、onscrollの基本的な操作を300ミリ秒ごとにスロットルします。スロットリングは、スクロールイベントハンドラの速度を低下させます。
パッシブイベント
最近、最新のWebブラウザは、scroll、touchstart、wheelなどの入力イベントでパッシブイベントをサポートするようになりました。これにより、UIスレッドは、カスタムイベントハンドラに制御を渡す前に、イベントをすぐに処理できます。
パッシブイベントをサポートするWebブラウザでは、preventDefault()を呼び出さないイベントリスナーにpassiveフラグを追加する必要があります。
document.addEventListener(
'scroll',
(event) => {
// handle scroll event
},
{ passive: true }
);
Code language: JavaScript (javascript)passiveオプションがない場合、イベントハンドラのコードは、UIスレッドがスクロールを実行する前に常に呼び出されます。
パッシブイベントをサポートしているブラウザについては、こちらをご覧ください。
まとめ
scrollイベントは、ウェブページまたは要素をスクロールしたときに発生します。- ページの場合、
scrollXとscrollYプロパティは、ドキュメントが現在水平方向と垂直方向にスクロールされたピクセル数を返します。 - 要素の場合、
scrollTopとscrollLeftプロパティは、要素のコンテンツが垂直方向にスクロールされたピクセル数と、左端からスクロールされたピクセル数を設定または取得します。 - スクロールイベントをより適切に処理するには、イベントスロットリングテクニックを使用します。最新のWebブラウザでは、パッシブイベントリスナーを使用できます。