概要: このチュートリアルでは、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); // null
Code 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ブラウザでは、パッシブイベントリスナーを使用できます。