絶対配置要素を介してマウスイベントを渡す


307

その上に絶対配置された別の要素を持つ要素のマウスイベントをキャプチャしようとしています。

現時点では、絶対配置要素のイベントがそれにぶつかり、その親に向かってバブルしますが、これらのマウスイベントに対して「透過」にして、その背後にあるものに転送したいと考えています。これをどのように実装すればよいですか?

回答:


488
pointer-events: none;

イベントが適用される要素を「通過」させ、「下」の要素でイベントを発生させるCSSプロパティです。

詳細については、https//developer.mozilla.org/en/css/pointer-eventsを参照してください。

IE 11まではサポートされていません。他のすべてのベンダーはかなり前からそれをサポートしています(グローバルサポートは12 / '16では〜92%でした):http : //caniuse.com/#feat=pointer-events(コメントにリンクを提供してくれた@ s4yに感謝) 。


3
ありがとう!これは、最新の(IE以外の)ブラウザーに最適なソリューションです。この質問が投稿された時点では、pointer-events存在していなかったと思います!ある時点で、受け入れられた回答をこの回答に切り替える場合があります。
s4y、2011年

16
うわー、これは私に何時間も節約しました。
ダンアブラモフ、2012年

2
受け入れた答えをこれに切り替えました。pointer-events それでものサポートはそれほど素晴らしいものはありませんが、改善されています。より互換性のあるオプションについては、@ JedSchmidtの回答を参照してください。
2012

1
ありがとう、これが実際に存在することを知りませんでした。時間を節約できました
Mohammed A. Al Jama 2014年

2
しかし、スクロールイベントなどの一部のイベントを通過させたいが、一番上の要素が他のすべてのイベントに応答するようにしたい場合はどうでしょう。pointer-eventsをnoneに設定すると、一番上の要素のすべてのイベントが強制終了されます。
AndroidDev 2017

50

必要なのがマウスダウンだけの場合は、次のdocument.elementFromPoint方法でメソッドを実行できる可能性があります。

  1. マウスダウンで最上層を削除し、
  2. xy座標をイベントからdocument.elementFromPointメソッドに渡して、その下の要素を取得し、次に
  3. 最上層を復元します。

9
より詳しい説明はこちら:vinylfox.com/forwarding-mouse-events-through-layers
Nathan

2
すごい、その方法が存在することさえ知りませんでした!また、whileループを使用してカーソルの下にあるすべての要素を取得し、最上位の要素を取得して、次の要素を見つけるために非表示にするのにも非常に簡単に使用できます。ここに私のバージョンを入手
jpeltoniemi

2
この回避策の問題は、ページのズームでは機能しないことです。モバイルデバイスやデスクトップブラウザーの場合、XY座標でズームしても意味がなくなり、ズームを計算する明確な方法がありません。ピンチズームは実際には不可能だと思います。
Impossibear

39

また
、親要素(おそらく透明なdiv)でポインターイベントを無効にして、子要素で有効にすることもできます。これは、任意のレイヤーの子要素をクリックできるようにしたい、複数の重複するdivレイヤーで作業する場合に役立ちます。このため、すべてのpointer-events: none子のdivはget とclick-childrenはポインタイベントを再度有効にします。pointer-events: all

.parent {
    pointer-events:none;        
}
.child {
    pointer-events:all;
}

<div class="some-container">
   <ul class="layer-0 parent">
     <li class="click-me child"></li>
     <li class="click-me child"></li>
   </ul>

   <ul class="layer-1 parent">
     <li class="click-me-also child"></li>
     <li class="click-me-also child"></li>
   </ul>
</div>

5
右の発見の高い後、恐ろしいpointer-events:noneと子ノードが影響を受けたの差し迫ったレットダウン、あなたは:)救う
フアン・コルテス

;)とても嬉しい
Allisone

簡単に言えば.parent * { pointer-events:all; }、子供向けですか?
ドミトリー

「pointer-events:auto;」である必要があります。「all」の値はSVGにのみ適用されます。developer.mozilla.org/en-US/docs/Web/CSS/pointer-eventsを
mattavatar

7

イベントを受信しない理由は、絶対配置された要素が「クリック」する要素(青のdiv)の子ではないためです。私が考えることができる最もきれいな方法は、クリックしたいものの子として絶対要素を置くことですが、私はあなたがそれを行うことができないか、あなたがこの質問をここに投稿しなかったと思います:)

別のオプションは、absolute要素のクリックイベントハンドラーを登録し、青いdivのクリックハンドラーを呼び出して、両方を点滅させることです。

イベントがDOMを介してバブルアップする方法のため、より簡単な答えがあるかどうかはわかりませんが、他の誰かが知らないトリックを持っているかどうか非常に興味があります!


応答をありがとう、Loktar。残念ながら、実際のページでは、絶対配置された要素の下に何があるのか​​はわかりません。可能なターゲットが複数ある可能性があります。私が考えることができる唯一の回避策は、マウスの座標を取得し、それらを可能なターゲットと比較して、それらが交差するかどうかを確認することです。それは単に厄介です。
s4y 2009年

4

あるdivから別のdivに手動でイベントをリダイレクトする利用可能なJavaScriptバージョンがあります。

私はそれをクリーンアップしてjQueryプラグインにしました。

これがGithubリポジトリです:https : //github.com/BaronVonSmeaton/jquery.forwardevents

残念ながら、私がそれを使用していた目的-Googleマップ上にマスクをオーバーレイすると、クリックイベントとドラッグイベントがキャプチャされず、マウスカーソルが変化しないため、IEとOperaでマスクを非表示にすることを決定しただけのユーザーエクスペリエンスが低下します-ポインタイベントをサポートしない2つのブラウザ。


1

マウスイベントを必要とする要素がわかっていて、オーバーレイが透明である場合は、それらのz-indexをオーバーレイよりも高い値に設定できます。もちろん、その場合、すべてのイベントがすべてのブラウザーで機能するはずです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.