JavaScript

レシピ

イベント

マウスカーソルの位置座標を取得する

マウスカーソルの位置座標を取得する方法について解説します。

この記事のポイント

  • マウスカーソルの位置座標の起点は4種類
  • 高解像度の場合は値に2を描ける

目次

マウスカーソルの位置座標は4種類の起点がある

マウスカーソルの位置座標は次のように横軸のX、縦軸のYの値を取得することができます。

マウスカーソルの位置座標を出力

位置座標は「どこを起点とするか」で違いがありますが、いずれも左上からの距離になります。

座標の起点プロパティ名
端末スクリーンscreenXscreenY
ブラウザの表示エリアclientXclientY
ページ先頭pageXpageY
HTML要素offsetXoffsetY

以降はそれぞれの起点から位置座標を取得する解説となります。

端末スクリーンを起点にする

スクリーンの左上を起点にしてマウスカーソルの位置座標を取得するときはscreenXプロパティscreenYプロパティを参照します。

スクリーンの左上を起点にした座標

以下のコードはsection要素をクリックすると、screenXプロパティscreenYプロパティを参照してconsole.logメソッドで出力します。

コード例

<!DOCTYPE html>
<html lang="ja">
<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>GRAYCODE JavaScript</title>
	<script>

		window.addEventListener('load', function(){
			document.getElementById("content1").addEventListener('click', logPosition);
		});

		function logPosition(event) {
			console.log("screenX: " + event.screenX);
			console.log("screenY: " + event.screenY);
		}

	</script>
</head>
<body>
<h1>JavaScriptレシピ</h1>
<section id="content1"></section>
</body>
</html>

もう少し具体的にコードを解説します。

まず、ページの読み込みが完了した時点でid属性content1」のsection要素にイベントリスナーでクリックイベントを登録しています。
これで、section要素がクリックされるとlogPositionメソッドが実行されるようになります。

logPositionメソッドはイベントリスナーからMouseEventオブジェクトを変数eventで受け取ります。
そこで、メソッド内でevent.screenXevent.screenYをそれぞれ参照して出力しています。

ブラウザの表示エリアを起点にする

ブラウザの表示するエリア左上を起点にしてマウスカーソルの位置座標を取得するときは、clientXプロパティclientYプロパティを参照します。
表示エリアを起点とするため、タブやURLバーなどの高さは含みません。

ブラウザの表示エリア左上を起点にした座標

以下のコードは先述の「端末スクリーンを起点にする」とほぼ同じ内容ですが、使用するプロパティのみ変更して出力しています。

コード例

<!DOCTYPE html>
<html lang="ja">
<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>GRAYCODE JavaScript</title>
	<script>

		window.addEventListener('load', function(){
			document.getElementById("content1").addEventListener('click', logPosition);
		});

		function logPosition(event) {
			console.log("clientX: " + event.clientX);
			console.log("clientY: " + event.clientY);
		}

	</script>
</head>
<body>
<h1>JavaScriptレシピ</h1>
<section id="content1"></section>
</body>
</html>

ページ先頭を起点にする

ページ先頭の左上を起点にしてマウスカーソルの位置座標を取得するときはpageXプロパティpageYプロパティを参照します。
上記のブラウザ表示エリアと似ていますが、ページを起点とするとスクロール量を含めた座標を取得することができます。

以下の例ではブラウザの表示エリアを起点にした位置座標と、ページの位置座標を同時に出力しています。
横スクロールはないためX座標は同じ値ですが、縦スクロールがあるためY座標は異なる値を取得することができます。

ページを起点にして座標を取得

以下のコードは上記の「ブラウザの表示エリアを起点にする」にページの位置座標の取得を追記しています。

コード例

<!DOCTYPE html>
<html lang="ja">
<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>GRAYCODE JavaScript</title>
	<script>

		window.addEventListener('load', function(){
			document.getElementById("content1").addEventListener('click', logPosition);
		});

		function logPosition(event) {
			console.log("clientX: " + event.clientX);
			console.log("clientY: " + event.clientY);
			console.log("pageX: " + event.pageX);
			console.log("pageY: " + event.pageY);
		}

	</script>
</head>
<body>
<h1>JavaScriptレシピ</h1>
<section id="content1"></section>
</body>
</html>

ページの先頭を起点にした位置座標を取得できるため、マウスカーソルがページのどの位置にあるかを把握するときに役立ちます。

HTML要素を起点にする

特定のHTML要素を起点にしてマウスカーソルの位置座標を取得するときはoffsetXプロパティoffsetYプロパティを参照します。

以下の例では青いエリアになっているsection要素の左上を起点として、クリックされたときの位置座標を出力しています。

HTML要素を起点にして座標を取得

以下のコードは上記の「ブラウザの表示エリアを起点にする」にページの位置座標の取得を追記しています。

コード例

<!DOCTYPE html>
<html lang="ja">
<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>GRAYCODE JavaScript</title>
	<script>

		window.addEventListener('load', function(){
			document.getElementById("content1").addEventListener('click', logPosition);
		});

		function logPosition(event) {
			console.log("offsetX: " + event.offsetX);
			console.log("offsetY: " + event.offsetY);
		}

	</script>
</head>
<body>
<h1>JavaScriptレシピ</h1>
<section id="content1"></section>
</body>
</html>

HTML要素のmarginプロパティは座標に含まれませんが、paddingプロパティborderプロパティは座標に含まれます。
ただしHTML要素を起点とするため、borderプロパティの上側と左側はマイナスの位置座標になることがあります。

以下の例は青いエリアがHTML要素、灰色がborderプロパティによる枠線です。
マウスカーソルが枠線の左上でクリックされると、座標の起点は青いエリアの左上となるためマイナスの位置座標が出力されます。

ボーダーの位置座標はマイナス

このように、borderプロパティは座標には含まれますが起点にはなりません。

高解像度ディスプレイの場合

MacのRetinaディスプレイなど高解像度ディスプレイ環境は通常ディスプレイ環境の2倍のピクセルが敷き詰められていますが、上記の全てのプロパティで取得できる値は通常ディスプレイと同じ値になります。
そのため、高解像度ディスプレイでピクセル数に応じた座標として取得したいときはプロパティの値に2を掛けてください。

コード例

<!DOCTYPE html>
<html lang="ja">
<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>GRAYCODE JavaScript</title>
	<script>

		window.addEventListener('load', function(){
			document.getElementById("content1").addEventListener('click', logPosition);
		});

		function logPosition(event) {
			if( window.devicePixelRatio === 1 ) {
				console.log("offsetX: " + event.offsetX);
				console.log("offsetY: " + event.offsetY);
			} else {
				console.log("offsetX: " + event.offsetX*2);
				console.log("offsetY: " + event.offsetY*2);
			}
		}

	</script>
</head>
<body>
<h1>JavaScriptレシピ</h1>
<section id="content1"></section>
</body>
</html>

window.devicePixelRatioプロパティは端末のピクセル比を参照することができ、「1」であれば通常のディスプレイ、「2」は高解像度ディスプレイになります。
そこで、if文の条件式でwindow.devicePixelRatioプロパティを参照して高解像度ディスプレイの場合のみoffsetXoffsetYの値を「*2」してピクセル数を計算してから出力しています。

こちらの記事は役に立ちましたか?

ありがとうございます。
もしよろしければ、あわせてフィードバックや要望などをご入力ください。

コメントありがとうございます!
運営の参考にさせていただきます。