jQueryの寸法系のメソッドは、DOMに対して大幅な変更が入っている部分もあります。
メソッド名が統一されていない例
IEがDHTMLとして入れたものをそのまま引き継いでいるという歴史的経緯もあってか、寸法系のプロパティは通常の要素とwindow
やdocument
で別物になっている例も多く、jQueryがそれを吸収していたりもします。
たとえば、scrollTop
やscrollLeft
はスクロールするエレメントにあるプロパティですが、window
やdocument
にはないので、これらでは代わりにwindow.pageYOffset
やwindow.pageXOffset
を取り出しています。
4段階の取得メソッド
jQueryでは、幅・高さの取得系メソッドは、3つ・4段階に分かれています。
-
width
/height
…中身とパディングの間が基準 -
innerWidth
/innerHeight
…パディングとボーダーの間が基準 -
outerWidth
/outerHeight
…ボーダーとマージンの間 -
outerWidth(true)
/outerHeight(true)
…マージンの外側
普通のエレメントの場合、jQueryの内部では中身、マージン、パディング、ボーダーなどをCSSとして取得して足し合わせる、というような処理を行っています。
ネイティブDOMで容易に取得できるのは、.clientWidth
/.clientHeight
でパディングの外側(jQueryのinner
系相当)、.getgetBoundingClientRect()
経由でボーダーの外側(jQueryのouter
系相当)などがあります。
そして、window
やdocument
については、jQueryで特殊な扱いをしています(width
だけ書きますが、height
も同じです)。
-
$(window).outerWidth()
…window.innerWidth
(スクロールバー込みの幅) -
$(window).innerWidth() & $(window).width()
…document.documentElement.clientWidth
(スクロールバー抜きの幅) -
$(document).***width()
(3つとも同じ)…「document.body
とdocument.documentElement
のscrollWidth
とoffsetWidth
(2×2=4通り)、document.documentElement.clientWidth
」の5つの中での最大値
offset
の違い
jQueryで書いてあった.offset().top
を機械的に.offsetTop
に置き換えたところ、値が合わない、ということが発生しました。調べてみると、
- jQuery…
.offset
の基準点はドキュメントの左上 - ネイティブ…
.offsetTop
の基準はoffsetParent ノード(position
をかけた要素など、ドキュメントの途中にも入りうる)
と、基準が違うとのことでした。ということで、ドキュメントの左上から測りたいときは、以下のjQueryのコードを参考に組み立てるのが良さそうです。
if ( !elem.getClientRects().length ) {
return { top: 0, left: 0 };
}
rect = elem.getBoundingClientRect();
doc = elem.ownerDocument;
docElem = doc.documentElement;
win = doc.defaultView;
return {
top: rect.top + win.pageYOffset - docElem.clientTop,
left: rect.left + win.pageXOffset - docElem.clientLeft
};