クリックイベントとpointer-eventsプロパティで透過クリックを実現する
CSS、クリックイベント、MouseEventを用いた要素透過クリックの実装
この解説では、CSS、クリックイベント、MouseEventを用いて、親要素(div要素など)をクリックしても、下位の要素をクリックできる方法を紹介します。
仕組み
この方法は、以下の2つの要素を組み合わせます。
- pointer-events プロパティ: 親要素の
pointer-events
プロパティをnone
に設定することで、マウスイベントを透過させます。 - MouseEvent オブジェクト: 下位要素をクリックした際に発生する
click
イベントのMouseEvent
オブジェクトを取得し、そのオブジェクトを用いて、親要素ではなく下位要素をクリックしたように処理を伝えます。
実装例
以下のコードは、親要素(div.parent
)をクリックしても、下位要素(button
)をクリックできる例です。
<div class="parent">
<button>ボタン</button>
</div>
.parent {
pointer-events: none;
}
const button = document.querySelector(".parent button");
button.addEventListener("click", (event) => {
// 親要素ではなく、下位要素をクリックしたように処理を伝えます。
const parent = event.target.parentNode;
const clickEvent = new MouseEvent("click", {
bubbles: true,
cancelable: true,
clientX: event.clientX,
clientY: event.clientY,
});
parent.dispatchEvent(clickEvent);
});
ポイント
pointer-events
プロパティは、IE 11 以前では対応していないため、古いブラウザでは動作しない可能性があります。MouseEvent
オブジェクトを作成する際は、bubbles
プロパティとcancelable
プロパティをtrue
に設定する必要があります。clientX
とclientY
プロパティは、クリックイベントが発生した場所の座標を指定します。
応用例
- 画像の上にテキストを重ねて表示し、画像をクリックできるようにする
- カードレイアウトで、カードをクリックすると詳細ページへ遷移する
- ドロップダウンメニューを開く
補足
上記以外にも、JavaScript ライブラリを用いて透過クリックを実装する方法もあります。
これらのライブラリを用いると、より簡単に透過クリックを実装することができます。
HTML
<div class="parent">
<button>ボタン</button>
</div>
CSS
.parent {
pointer-events: none;
}
JavaScript
const button = document.querySelector(".parent button");
button.addEventListener("click", (event) => {
// 親要素ではなく、下位要素をクリックしたように処理を伝えます。
const parent = event.target.parentNode;
const clickEvent = new MouseEvent("click", {
bubbles: true,
cancelable: true,
clientX: event.clientX,
clientY: event.clientY,
});
parent.dispatchEvent(clickEvent);
});
このコードをブラウザで実行すると、div.parent
要素をクリックしても、button
要素がクリックされます。
動作確認
このコードを動作確認するには、以下の手順を行います。
- HTMLファイルとCSSファイルを同じフォルダに保存します。
- JavaScriptファイルをHTMLファイルに読み込みます。
- ブラウザでHTMLファイルを開きます。
div.parent
要素をクリックします。
CSS、クリックイベント、MouseEvent 以外にも、透過クリックを実現する方法はいくつかあります。
方法
- z-index プロパティ: 下位要素の
z-index
プロパティを親要素よりも高く設定することで、下位要素を前面に表示し、クリックできるようにします。 - position プロパティ: 下位要素の
position
プロパティをabsolute
またはrelative
に設定し、親要素の座標系から独立した位置に配置することで、クリックできるようにします。 - pointer-events プロパティ: 下位要素の
pointer-events
プロパティをauto
に設定することで、親要素のpointer-events
プロパティの影響を受けずにクリックできるようにします。 - JavaScript フレームワーク: Vue.js や React などの JavaScript フレームワークを用いて、透過クリックを簡単に実装することができます。
各方法の比較
方法 | 利点 | 欠点 |
---|---|---|
z-index プロパティ | 簡単 | 重なり合った要素の順序を意識する必要がある |
position プロパティ | 柔軟性が高い | 複雑なレイアウトには不向き |
pointer-events プロパティ | シンプル | 古いブラウザでは対応していない |
JavaScript フレームワーク | 簡単 | フレームワークの知識が必要 |
z-index プロパティ
<div class="parent">
<div class="child">
<button>ボタン</button>
</div>
</div>
.parent {
height: 100px;
width: 100px;
background-color: red;
}
.child {
position: absolute;
top: 0;
left: 0;
height: 100px;
width: 100px;
background-color: blue;
z-index: 1;
}
.child button {
height: 50px;
width: 50px;
}
position プロパティ
<div class="parent">
<div class="child">
<button>ボタン</button>
</div>
</div>
.parent {
height: 100px;
width: 100px;
background-color: red;
}
.child {
position: relative;
top: 50px;
left: 50px;
height: 50px;
width: 50px;
background-color: blue;
}
.child button {
height: 50px;
width: 50px;
}
pointer-events プロパティ
<div class="parent">
<div class="child">
<button>ボタン</button>
</div>
</div>
.parent {
height: 100px;
width: 100px;
background-color: red;
pointer-events: none;
}
.child {
height: 100px;
width: 100px;
background-color: blue;
}
.child button {
height: 50px;
width: 50px;
}
JavaScript フレームワーク
Vue.js
<div id="app">
<div class="parent">
<div class="child">
<button>ボタン</button>
</div>
</div>
</div>
const app = new Vue({
el: "#app",
data: {
parent: {
pointerEvents: "none",
},
child: {
//
},
},
});
React
<div id="app">
<div className="parent">
<div className="child">
<button>ボタン</button>
</div>
</div>
</div>
const App = () => {
const [parent, setParent] = React.useState({
pointerEvents: "none",
});
const [child, setChild] = React.useState({
//
});
return (
css click mouseevent