初めて自分の家と他人の家が違う、と意識した時

以下のような構造になっています、実際はもう少し複雑になります。子要素の数も不確定。
id=divbox上でクリックしたらid=divboxの左端からの位置を取得したいのですが
子要素上でクリックするとその子要素の左端からの位置になってしまいます
右のほうの白い(=子要素のない)部分だとちゃんと取得できます。
id=divboxの半分の位置でクリックしたとき子要素に影響されずに300前後を取得できるようにするにはどういう風に書けばいいのでしょうか。
<html>
<head>
<title>Test</title>
<style>
#divbox {border:solid 1px blue;width:600px;height:20px;}
#divbox div{display:inline-block;height:100%;}
</style>
</head>
<body>
<div onclick="alert(event.offsetX)" id="divbox">
<div style="width:200px;background-color:orange;">a</div><div style="width:200px;background-color:gray;">b</div>
</div>
</body>
</html>

※webkit系で動けば他はどうでもいいです

A 回答 (2件)

event.offsetX の定義はイベントターゲットのパディング辺からの距離です。



WebKit 系に限定するなら、布置要素のボーダー辺からの距離(感知範囲はボーダーボックス)を返す event.layer(X|Y) があります。ただし、これは NN4 由来で Firefox もサポートしてはいますが、現状で標準化案すらありません。いつ廃止されてもおかしくないことを念頭に置いて下さい。

<div id="DIVBOX"
 onclick="alert ([ event.layerX, event.layerY ]); "
 style="position: relative">
...
</div>

もし #divbox 内に別の布置要素(例えば絶対配置された要素)がありうるなら No.1 の考え方で良いのですが、若干面倒な問題があります。現行の WebKit 系なら getBoundingClientRect() があるので以下の方が無難と考えます。これは event.client(X|Y) と同じく表示域から、ボーダー辺までの距離を得られます。

<div id="DIVBOX"
 onclick="
  var b = event.currentTarget.getBoundingClientRect ();
  alert ([event.clientX - b.left, event.clientY - b.top ]); ">
...
</div>

---
なお、IE を考慮してスクロール量を得るときは面倒でも document.compatMode で標準・互換モードを確認して下さい。No.1 の方法では、CSS の書き方によっては不具合が生じます。IE を考慮しないなら window.scroll(X|Y) または page(X|Y)Offset で十分です。

関連して、No.0 の HTML の書き方は間違っているので必ずチェックして下さい。そのままでは互換モードになります。

この回答への補足

<!DOCTYPE html>で標準モード

補足日時:2010/11/14 20:47
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
event.layerXで解決しました!
廃止されないことを祈ろう・・・

お礼日時:2010/11/14 20:46

//for Prototype: cumulativeOffset


function cumulativeOffset(element) {
var valueT = 0, valueL = 0;
do {
valueT += element.offsetTop || 0;
valueL += element.offsetLeft || 0;
element = element.offsetParent;
} while (element);
return { x: valueL, y: valueT };
}

//クライアント領域における要素位置
function clientOffset(element) {
var de = document.documentElement, db = document.body;
var top = de.scrollTop || (db ? db.scrollTop : 0);
var left = de.scrollLeft || (db ? db.scrollLeft : 0);
var obj = cumulativeOffset(element);
return { x: obj.x - left, y: obj.y - top };
}

onclick="
var obj = clientOffset(this);
alert('左端から' + (event.clientX - obj.x) + '上端から' + (event.clientY - obj.y));
"
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
2つ下の質問
『重なった要素上でのイベントで下層要素を特定したい』
http://okwave.jp/qa/q6316242.html
を見たところ
/* p 要素をスルーして背面の要素にマウスイベントを通知する */
p { pointer-events: none }
このようなものがありました!

cssでdivboxの子要素にpointer-events: noneを指定してみたところ
説明どおり子要素をスルーしてdivboxのevent.offsetXが取得できました。

ここを訪れた人の参考になると幸いです。
※pointer-events: none;の対応ブラウザには注意してください

お礼日時:2010/11/14 22:31

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!


おすすめ情報