0
0

More than 1 year has passed since last update.

クリックされた点に重なっている要素をすべて取得する

Last updated at Posted at 2023-03-05

やりたいこと

任意の点をクリックしたとき、重なっている要素すべてを取得したい。
( 例えば x をクリックした場合は A, B, D を取得)
image.png

それぞれの要素は position: absolute などで位置が指定されており、親子関係にない。
そのためイベントのバブリングでは実現できない、というケース。

document.elementsFromPoint

こういう場合は document.elementsFromPoint を使うと楽に取得できる。

MDNによると「実験的な機能」らしいので、念のためにポリフィルを導入する。

サンプルコード

click イベントを範囲広めに設定して、 clientX clientYelementsFromPoint に渡すだけ。超らくちん。
ただし、 elements には body や html 要素も含まれるので、不要なら自前で取り除く必要がある。

document.addEventListener('click', e => {
  const elements = document.elementsFromPoint(e.clientX, e.clientY)

  elements
    .filter(element => {
      // 不要な要素は自前で取り除く
      const tagName = element.tagName.toLowerCase()
      return !['html', 'body'].includes(tagName)
    })
    .forEach(element => {
      // 何かの処理
    })

})

--

もしそれぞれの要素の click イベントを発火させたい場合は filter で e.target を除いてから dispatchEvent を呼ぶと良さげ。
(そうしないとイベントが二重に呼ばれちゃうから)

document.addEventListener('click', e => {
  const elements = document.elementsFromPoint(e.clientX, e.clientY)

  elements
    .filter(element => {
      return element !== e.target
    })
    .forEach(element => {
      element.dispatchEvent(new MouseEvent('click'))
    })
})

document.getElementById('A').addEventListener('click', e => { alert('A') })
document.getElementById('B').addEventListener('click', e => { alert('B') })
document.getElementById('C').addEventListener('click', e => { alert('C') })
document.getElementById('D').addEventListener('click', e => { alert('D') })
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0