osgsm.io
HomeNotesJavaScript で特定の要素の中でマウスイベントが生じた位置を取得する

JavaScript で特定の要素の中でマウスイベントが生じた位置を取得する

Published Feb 18, 2025
Updated Mar 12, 2025

例えば、 a 要素内でマウスイベントが生じた位置を取得しようと、次のように MouseEvent.clientX などを使っても、ビューポートにおけるイベントが生じた位置しか取得できない。

TypeScript
const el = document.querySelector('a');
 
el?.addEventListener('mousemove', (event: MouseEvent) => {
  console.log({ x: event.clientX, y: event.clientY });
});

仮に、ビューポート内で要素が左端から 40px、上端から400pxの位置にあるとして、その要素の左上端でマウスイベントが生じた場合、 event.clientX40 になり、 event.clientY400 になる。

特定の要素の中でイベントが発生した位置を取得したい場合、上述のケースでは、それぞれ 0 を取得したい。

これを実現するには、 Element.getBoundingClientRect() を使う。このメソッドは DOMRect object を返すが、この object には、その要素のサイズとビューポートを基準とした位置が含まれる。

DOMRect のプロパティについては、MDN の画像がわかりやすい(下図参照)。

DOMRect object that is the smallest rectangle containing the entire element.
Element: getBoundingClientRect() method - Web APIs | MDN

したがって、イベントリスナーがアタッチされている要素で getBoundingClientRect() をコールし、返された object の lefttop の値を event.clientXevent.clientY から引く。

TypeScript
el?.addEventListener('mousemove', (event: MouseEvent) => {
  if (!(event.currentTarget instanceof HTMLAnchorElement)) return;
 
  const targetRect = event.currentTarget.getBoundingClientRect();
 
  console.log({
    x: event.clientX - targetRect.left,
    y: event.clientY - targetRect.top,
  });
});

これで、 a 要素の左上端でイベントが生じた場合に 0, 0 を取得できる。


参考