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
};