★Webページ作成支援~Simple Style★

マウスの座標を取得する(Mouse coordinate)

マウスカーソルの位置に合わせたレイヤ表示などを行いたい場合などには、マウス座標の情報は欠かせません。
これらを実現する為に、JavaScriptにはイベントと言う概念があります。

イベントとは、マウスの移動やクリック、キーボード操作などといった特定の動作を指します。
イベントハンドラは、このイベントを検出し、イベントに処理を与えるのに使用します。イベントハンドラによって、発生したイベントごとに処理を実行することができます。

※Internet Explorerは、分かりやすいよう IE と省略している部分があります。
※2017年5月、最新ブラウザにて検証した結果、追記/修正している部分があります。

マウスイベント

マウスを動かしたり、ボタンを押したりした際に、それらをイベントと見なして処理するように指定するには、以下のようにします。
document.イベント名=起動させたい関数名
HTMLのイベント属性を利用せず、JavaScriptでイベントハンドラの内容を直接指定する方法です。
通常、関数の呼び出しには関数名の後ろに()が必要ですが、この場合は不要です。

Example
document.getElementById("test").onmouseover = myFunction;


マウスイベントの主なイベントハンドラ
onMouseOver マウスが乗った時に発生
onMouseOut マウスが離れた時に発生
onMouseUp マウスで押していたのを離した時に発生
onMouseDown マウスで押した時に発生
onMouseMove マウスを動かしている時に発生
マウス座標の取得などでよく利用されます。

マウス座標を取得する関数

マウス操作で起動されるべき関数の形は以下のようになります。
function 関数名(e) {
 //処理
}
引数に指定された e には、Internet Explorer(※)以外(Firefoxなどの Mozilla系ブラウザ、Opera及び Safariなど)では引き渡されるイベントオブジェクトが入ります
Internet Explorer以外では、このオブジェクトのプロパティ値を取得する事でマウスの情報を取得します。

一方、Internet Explorerでは、event と言う名のイベントオブジェクトが別に定義されているので、これに対するプロパティを取得します。
以上より、引数が有効なオブジェクトであれば(IE以外)、それのプロパティ値を取得するようにして、そうでなければ(IEのみ) event オブジェクトのプロパティ値を取得するようにすれば良い訳です。

以下のように記述します。
function 関数名 (e) {
 if (e) { // IE以外
  (IE以外での処理)
 }
 else { // IEのみ
  (IE専用の処理)
 }
}

(※)古いバージョンのIEを指します。
2017年現在では、IE9、IE11、Microsoft Edgeでイベントオブジェクトを取得できます。

Internet Explorerでのマウス座標の取得方法

マウス座標については、スクロールを加味したものであるかどうかを考える必要があります。
単純にクライアント領域から見た座標をそのまま用いた場合、スクロール分の嵩上げを忘れると、クライアント領域外での処理になってしまう事があります。
これは、Internet Explorerでのみ問題になります。

Internet Explorerの場合は event オブジェクトのプロパティ値を取得します。

event.clientX クライアント領域上に於ける、マウスカーソルのX座標を取得します。
event.clientY クライアント領域上に於ける、マウスカーソルのY座標を取得します。

このとき注意したいのは、どちらもスクロールを加味していないものであると言う事です。
そこで、スクロール量を別のプロパティから取得する事になるのですが、後方互換モードと標準準拠モードで値を得られるプロパティが異なります。


標準/後方互換モードの違い
互換 document.body.scrollLeft 横スクロールの量をピクセル単位で与えます。つまり、クライアント領域の左端は実際の描画空間の左端より何ピクセルずれているかを与えます。
標準 document.documentElement.scrollLeft
互換 document.body.scrollTop 縦スクロールの量をピクセル単位で与えます。つまり、クライアント領域の上端は実際の描画空間の上端より何ピクセルずれているかを与えます。
標準 document.documentElement.scrollTop

後方互換モードか標準準拠モードかを調べてそれに応じて処理を振り分けても良いのですが、以下のよう記述してもよいでしょう。
mouseX = event.clientX + (document.body.scrollLeft || document.documentElement.scrollLeft);

mouseY = event.clientY + (document.body.scrollTop || document.documentElement.scrollTop);
これは、二つあるプロパティのうち、対応していない方は必ず null となる事によるものです。
スクロールが全くされていない場合、対応している方はゼロ値で、もう片方は null となります。

Internet Explorer以外でのマウス座標の取得方法

Internet Explorer以外(Firefoxなどの Mozilla系ブラウザ、Opera及び Safariなど)では、起動した関数の引数として与えられたオブジェクトのプロパティ値を取得します。

※引数名は e と言う決まりはありません。
e.pageX 表示空間上に於ける、マウスカーソルのX座標を取得します。
当然スクロールも加味されています。
e.pageY 表示空間上に於ける、マウスカーソルのY座標を取得します。
当然スクロールも加味されています。

尚、スクロールを加味しない値が欲しい場合には、スクロール量をこれらの値から差し引けば良い事になります。しかし、Opera 9.5ではマウスイベント時にスクロール量を正しく得る事が出来ないと言う不具合があります。

以上の事から、スクロール量を差し引く演算はイヴベント時に起動される関数外で成されなければなりません。
加えて、スクロール量を取得するプロパティは、Moszilla系ブラウザ及びSafariでは以下のようになります。
window.pageXOffset横スクロールの量をピクセル単位で与えます。
window.pageYOffset縦スクロールの量をピクセル単位で与えます。

※Microsoft Edge、IE11では上記のプロパティで取得できます。(2017年5月)

マウス座標を取得する関数のまとめ

以上をまとめると、マウス座標を取得する関数であれば、以下のように記述します。
ここでは、マウス座標を mouseX 及び mouseY と言うグローバル変数に収めるものとします。

JavaScript
var mouseX = 0;
var mouseY = 0;
function 関数名(e) {
  // スクロール量を取得する
  const propType = (document.documentElement)?
    document.documentElement:document.body;
  var scrlx = window.pageXOffset || propType.scrollLeft;
  var scrly = window.pageYOffset || propType.scrollTop;
  if(e){ // FireFox
    mouseX = e.pageX;
    mouseY = e.pageY;
  }
  else{ // IE
    mouseX = event.clientX + scrlx;
    mouseY = event.clientY + scrly;
  }
}

サンプルソース

マウスの座標を取得して、マウスが動くたびに座標を表示しています。
スタイルシートは外部ファイル「style.css」で指定。
HTML
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>マウスの座標を取得</title>
</head>
<body>
<div id="main">
<h2>マウスポインタ座標表示</h2>
<form name="myForm">
  <p>
  <span class="cap">座標X:</span>
  <input type="text" name="msx" size="10">
  </p>
  <p>
  <span class="cap">座標Y:</span>
  <input type="text" name="msy" size="10">
  </p>
</form>

<script type="text/javascript">
document.addEventListener('mousemove',function(evt){
  const FORM  = document.myForm;
  const propType = (document.documentElement)?
    document.documentElement:document.body;
  var scrlx = window.pageXOffset || propType.scrollLeft;
  var scrly = window.pageYOffset || propType.scrollTop;
  var mouseX;
  var mouseY;

  if(evt){ // Firefox,IE9+,Edge,Chrome
    mouseX = evt.pageX;
    mouseY = evt.pageY;
  }
  else{ // other than Firefox
    mouseX = event.clientX + scrlx;
    mouseY = event.clientY + scrly;
  }
  FORM.msx.value = mouseX;
  FORM.msy.value = mouseY;
}, false);
</script>
</div>
</body>
</html>

style.css
@charset "UTF-8";
body {
  color : #000;
  font-size : 12px;
}
#main {
  margin : 0;
  position : absolute;
  top : 60px;
  left : 50px;
}
h2 {
  font-size : 13px;
}
.cap {
  padding : 2px 5px;
  width : 60px;
  height : 32px;
  line-height : 28px;
  background-color : #bbeebb;
}
input {
  padding : 0px 5px;
  border : 1px solid #ccc;
}

サンプルの表示

マウスのXY座標の表示サンプルを実行できます。
下記をクリックしてください。
DEMO

プロパティ別にマウスの座標を表示するサンプルです。
どのプロパティが有効か分かります。
DEMO
ラインを表示