jQuery入門道場 jQueryの使い方

3章 属性、CSS操作

座標位置

.offset()と.position()を見てみます。.offset()は、簡単です。.position()は、少し曲者です。しかし、この2つのメソッド、日本人の私が言うのも何ですが、直感的にはメソッド名を逆にした方が良かったでしょう…。

.offset()

.offset()

マッチした要素の最初の要素のHTMLドキュメントに対する相対位置を返します。leftとtopをプロパティに持つオブジェクト形式で返ります。

(ドキュメント上での左上からの位置であり、ブラウザウインドウ(viewport)の左上からの位置とは区別しておきましょう。 つまり縦長のサイトで、ずーと下にスクロールしてようやく出てきた要素は、その分の高さがtopに加わっています)

<style>
* {
  margin: 0;
  border: 0;
  padding: 0;
}
#outside {
  background-color: beige;
  margin: 50px;
  padding: 20px;
}
#inside {
  background-color: gold;
  margin: 10px;
}
</style>
 
<div id="outside">
  <div id="inside">
  
  </div>
</div>
var xy;
xy = $("#outside").offset();
console.log(xy);
 
xy = $("#inside").offset();
console.log(xy);

実際のサンプル

Firebugなどで確認すると、次の結果になります。

上記の場合、xy.top、xy.leftなどとして、値を取り出せます。

.offset(coordinates)

下で出てくるposition()と異なり、.offset()は位置の設定に使うこともできます。topとleftをプロパティに持つオブジェクトを引数に指定します。

$("#outside").offset({top: 100, left: 200});

もし指定した要素のCSSのpositionの値がstaticの場合は、座標位置を変更するために、relativeに変更されます。

.position()やや中級

CSSのposition: xxxの知識を必要とするため、やや中級者向けかも知れません。 .offset()が、HTMLドキュメントからの相対位置を返すのに対し、.position()は、offset parentからの相対位置を返します。offset parentと聞きなれない言葉が出てきましたが、これは、jQueryでは、CSSのpositionでstatic以外(relative, absolute, fixed)に設定されている直近の先祖要素を指します。もし、relativeなどを一切使っていなければ、HTMLドキュメントからの相対位置を返すため、.offset()と同じか又は似たような値になります。(offset()とは、マージンの扱いに違いあり)

この.position()では、時折「親要素からの相対位置」という解説を見かけますが、これでは説明不足で、誤解を招きます。更にメソッド名が紛らわしいせいか、.offset()と完全に取り違えて覚えている方もいます。

具定例を見てみましょう。.offset()の例もついでに見てみます。

<style>
* {
  margin: 0;
  border: 0;
  padding: 0;
}
#outside {
  background-color: beige;
  position: absolute;
  top: 100px;
  left: 100px;
  width: 100px;
  height: 100px;
}
#inside {
  background-color: gold;
  position: relative;
  top: 30px;
  left: 30px;
  width: 30px;
  height: 30px;
}
</style>
 
<div id="outside">
  <div id="inside">
  
  </div>
</div>
var xy;
xy = $("#outside").offset();
console.log(xy)
 
xy = $("#outside").position();
console.log(xy)
 
xy = $("#inside").offset();
console.log(xy)
 
xy = $("#inside").position();
console.log(xy)

実際のサンプル

Firebugなどのコンソール画面で確認すると、次の結果になります。

CSSで親要素をposition: absolute;にして子要素をposition: relative;にすると、子要素は、親要素からの相対位置で配置されます。 最初の2つは同じ結果になっています。3つ目は、100pxと30pxが足されて、130pxになっています。そして一番のポイントは、一番最後の.position()です。insideのoffset parentは、outsideなので、outsideからの相対位置が取得されます。

もしまだ余裕のある方は、もう一例見てみましょう。入門者の方は、飛ばして下さい。.offset()と.position()のマージンの取り扱いの違いを見てみます。HTMLとCSSは、.offset()で使ったものと同じです。

<style>
* {
  margin: 0;
  border: 0;
  padding: 0;
}
#outside {
  background-color: beige;
  margin: 50px;
  padding: 20px;
}
#inside {
  background-color: gold;
  margin: 10px;
}
</style>
 
<div id="outside">
  <div id="inside">
  
  </div>
</div>
var xy;
xy = $("#outside").offset();
console.log(xy);
 
xy = $("#outside").position();
console.log(xy);
 
xy = $("#inside").offset();
console.log(xy);
 
xy = $("#inside").position();
console.log(xy);

実際のサンプル

Firebugなどのコンソール画面で確認すると、次の結果になります。

今度は、position: relative;などを使っていないため、.offset()と.position()は、同じ結果になると思いたいところでしたが、違う結果になりました。 よくよく見てみると、マージン分に差があります。つまり、.offset()の場合は、マージンを含まない箇所を左上として計算しているの対し、.position()の場合は、マージンを含めた箇所を左上として計算しています。