HOWTO · JavaScript

JavaScript でマウスの位置を追跡する

このチュートリアルでは、マウスイベントを使用して JavaScript でマウスの位置を追跡する方法を理解します。

このページの内容

ブラウザーの mousemove イベントにコールバックを登録すると、ポインターの動きを追跡できます。コールバックには MouseEvent が渡されるため、ポインターの状態を別に保持するのではなく、そのイベントから座標プロパティを読み取ります。このイベントはウィンドウ上でポインターが動くたびに発生するので、ハンドラーは動きごとに最新の位置を確認できます。

mousemove イベントでマウスの動きを検出する

イベントリスナーには、イベントの種類とコールバックを指定します。以下のブラウザー例では、window.addEventListener を使って handleMouseMove を mousemove に登録し、コールバック内で pageX、pageY、clientX、clientY を読み取ります。プロパティ名は大文字と小文字を区別します。mousemove イベントはポインターが動いたときに発生します。ページが読み込まれただけの場合や、ポインターが静止している場合には発生しません。

短い実行可能な例では、コールバックでイベントの値をどのように整形するかを示します。プレーンオブジェクトはプロパティ名を説明するための入力例です。対話的なページでは、実際のブラウザーの MouseEvent を使ってください。

この例を実行します:

このセクションのコードと表示されるラベルや出力は英語のままです。

function handleMouseMove(event) {
  console.log(
    `page: (${event.pageX}, ${event.pageY}); client: (${event.clientX}, ${event.clientY})`
  );
}

handleMouseMove({ pageX: 120, pageY: 240, clientX: 120, clientY: 240 });

ブラウザー上で動作を確認するには、次の自己完結型ページを使います。コンテンツを縦長にしてあるためページをスクロールでき、ポインターがページ上で動くたびにハンドラーが両方の座標ペアを記録します。

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Mouse coordinates</title>
  <style>
    body { min-height: 1600px; font: 16px sans-serif; }
    main { padding: 2rem; }
  </style>
</head>
<body>
  <main>
    <h1>Move the pointer, then scroll</h1>
    <p>Open the browser developer console to compare the coordinate pairs.</p>
  </main>
  <script>
    window.addEventListener('mousemove', (event) => {
      console.log(
        `page: (${event.pageX}, ${event.pageY}); client: (${event.clientX}, ${event.clientY})`
      );
    });
  </script>
</body>
</html>

ページ座標とビューポート座標の使い分け

pageX と pageY は、ドキュメントの左上を原点としてポインターの位置を測ります。ドキュメントのスクロール量が含まれるため、読者がスクロールしてもコンテンツ上の位置を基準にしたい場合に便利です。たとえば、長いドキュメント内のどこに点があるかを記録するときは、ページ座標を使います。

clientX と clientY は、表示中のビューポートの左上を原点として測ります。スクロールしても原点は変わりません。カスタムカーソルの目印やビューポート上のオーバーレイなど、現在ブラウザーに表示されている範囲内で何かを配置したり比較したりするときに使います。

この2組は異なる座標空間を表すため、計算ではどちらか一方の組を一貫して使ってください。ページ座標とビューポート座標を混ぜると、スクロール量の分だけ結果がずれることがあります。要素をポインターに追従させるには、追加のマウスイベントと要素の位置を調整する処理も必要です。座標を読み取るだけでは、要素は移動しません。

スクロールしながら pageX と clientX を比較する

スクロールする前はドキュメントの原点とビューポートの原点が一致するため、水平方向の pageX と clientX は同じ値になり、pageY と clientY も同じ値になります。ポインターを動かし、コンソールで両方の座標ペアを確認してください。最初の画像は、スクロール前にコンソールを確認するためのものです。

スクロール前のページ座標とビューポート座標を表示するブラウザー開発者コンソール

下方向にスクロールすると、水平方向の値は通常そろったままですが、垂直方向の pageY にはスクロールした距離が含まれ、clientY はビューポートの上端からの位置を表します。垂直方向の値の差は、現在のスクロール量に対応します。2枚目の画像は、スクロール後にコンソールを確認するためのものです。

スクロール後に異なる pageY と clientY の値を表示するブラウザー開発者コンソール

現在表示されている範囲を基準に位置を表す場合は、clientX と clientY を選びます。スクロールしたコンテンツを含むドキュメント上の位置を基準にする場合は、pageX と pageY を選びます。ブラウザーのマウスイベント全般については、MDN の Mouse Events リファレンスを参照してください。