- ベストアンサー
重なった要素上でのイベントで下層要素を特定したい
例えば2つ以上のonclickが設定されたDIV要素が重なっている場合、 その上でクリックをするとz-index的に上にある要素しか反応しませんが、 その下にある要素も処理したい場合には、どのように特定すればいいでしょうか。 下層要素のonclick等の処理が走る必要は無く、あくまで対象要素の特定、取得ができればOKです。 各要素の座標とサイズ、及びマウス座標から算出すれば一応可能ですが、 もっとスマートな方法を探しています。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
// CSSOM-View : MSHTML if ('undefined' !== typeof document.elementFromPoint /*@cc_on @set @v = (5.5 <= @_jscript_version && @_jscript_version <= 5.8) @*/) document./*@if (@v) attachEvent ('on' + @else@*/ addEventListener (/*@end@*/'click', function (e) { for ( var x = e.clientX, y = e.clientY, // [BUG] some browsers need e.page(X|Y) d = e./*@if (@v) srcElement @else@*/ target /*@end@*/.ownerDocument, r = d.documentElement, c = null, p = [ ], v = [ ], n, s; c !== r; c = n ) { n = d.elementFromPoint (x, y); if (n && n !== c) { p[p.length] = n; s = n.style; v[v.length] = s.visibility; s.visibility = 'hidden'; continue; } break; } for (var i = 0; n = p[i]; i++) n.style.visibility = v[i]; alert (p); }, false);
その他の回答 (2)
- Chaire
- ベストアンサー率60% (79/130)
No.2 補足。 > 大筋 document.elementFromPoint(event.clientX, event.clientY) で要素を識別後、それを { visibility: hidden } し、同座標で背面にある要素を識別します({ display: none } では再描画が走る可能性がある)。それを null あるいは同要素の繰り返しになるまで続けます(実際問題として非表示によって背面要素を得られる確証はない)。 要素識別時に @style の visibility 値を保存しておき、後で復元します。指定されてなければ空文字列が返るはずです。復元時の style.visibility = '' は style.removeProperty('visibility') の構文糖衣のため(CSSOM: 5.5.1)、上記の { visibility: hidden } を除去します。 なお、ブラウザによっては数ピクセルずれたりなど振る舞いの一致は保証しませんので工夫して下さい。例えば、Opera 10 や Safari 3 などでは event.pageX、event.pageY でないと期待通りにならない不具合があります。 > イベントバブリングの制御のような 描画制御は DOM3-Views&Formatting で策定していましたが、2004 年に中止され実装もありません。ご存知のように、各ブラウザは MSIE の offset*、client*、scroll* などの描画プロパティを独自にサポートしたため、混乱を極めています。現在 CSSOM-View 草案が事態の収拾に努めていますが、人手不足のため遅々としています。モバイル機器など端末の多様化もあり、少なくともあと数年は描画制御の標準化は見込めないと思います。 なお、No.0 に > 下層要素のonclick等の処理が走る必要は無く とありますが、実はこちらの方なら現在でも手段が用意されています。 /* p 要素をスルーして背面の要素にマウスイベントを通知する */ p { pointer-events: none } これは SVG のものですが、確認した限りでは Firefox 3.6 と Safari 4.1 は HTML 文書でサポートしています。
- think49
- ベストアンサー率59% (285/482)
document.addEventListener('click', function (event) { alert(event.target); }, false); element.addEventListener - MDC https://developer.mozilla.org/ja/DOM/element.addEventListener
お礼
回答ありがとうございます。 しかしすみません、そのコードの意図が分かりません。 それだと、一番上にある要素しか処理が走らないと思うのですが・・・
お礼
回答ありがとうございます。 elementFromPointメソッドなんてものがあったんですね。 コードをきちんと読み取れてはいませんが、 対象と成り得る全ての要素に対して、visibility:hiddenを1つずつかけながら、 その都度elementFromPointでチェックしていく、というのが大筋でしょうか。 しかし、こういったトリッキー?なコードが出てくるということは、 やはりイベントバブリングの制御のような便利機能は提供されていないんでしょうか・・・ ありがとうございました。