ブラウザウィンドウの幅と高さをどのように取得すればよいでしょうか?スクロールアウトした部分を含め、ドキュメントの全幅と高さをどのように取得すればよいでしょうか?JavaScript を使用してページをどのようにスクロールすればよいでしょうか?
このタイプの情報については、<html>
タグに対応するルートドキュメント要素 document.documentElement
を使用できます。ただし、考慮すべき追加のメソッドと特殊性があります。
ウィンドウの幅/高さ
ウィンドウの幅と高さを取得するには、document.documentElement
の clientWidth/clientHeight
を使用できます。
たとえば、このボタンはウィンドウの高さを表示します。
window.innerWidth/innerHeight
ではないブラウザは、window.innerWidth/innerHeight
のようなプロパティもサポートしています。それらは私たちが求めているもののように見えるので、代わりにそれらを使用しないのはなぜですか?
スクロールバーが存在し、それがいくつかのスペースを占めている場合、clientWidth/clientHeight
はそれなしで(それを差し引いて)幅/高さを提供します。言い換えれば、コンテンツで使用可能なドキュメントの可視部分の幅/高さを返します。
window.innerWidth/innerHeight
はスクロールバーを含みます。
スクロールバーが存在し、それがいくつかのスペースを占めている場合、これら2行は異なる値を表示します。
alert( window.innerWidth ); // full window width
alert( document.documentElement.clientWidth ); // window width minus the scrollbar
ほとんどの場合、スクロールバー内(もしあれば)に何かを描画または配置するために、利用可能なウィンドウ幅が必要になるため、documentElement.clientHeight/clientWidth
を使用する必要があります。
DOCTYPE
が重要注意: HTML に <!DOCTYPE HTML>
がない場合、トップレベルのジオメトリプロパティは少し異なる動作をする可能性があります。奇妙なことが起こる可能性があります。
最新の HTML では、常に DOCTYPE
を記述する必要があります。
ドキュメントの幅/高さ
理論的には、ルートドキュメント要素が document.documentElement
であり、すべてのコンテンツを囲んでいるため、ドキュメントの全サイズを document.documentElement.scrollWidth/scrollHeight
として測定できます。
ただし、その要素では、ページ全体に対して、これらのプロパティは意図したとおりに機能しません。Chrome/Safari/Opera では、スクロールがない場合、documentElement.scrollHeight
は documentElement.clientHeight
よりも小さくなることさえあります!奇妙ですよね?
ドキュメントの全高を確実に取得するには、これらのプロパティの最大値を取得する必要があります。
let scrollHeight = Math.max(
document.body.scrollHeight, document.documentElement.scrollHeight,
document.body.offsetHeight, document.documentElement.offsetHeight,
document.body.clientHeight, document.documentElement.clientHeight
);
alert('Full document height, with scrolled out part: ' + scrollHeight);
なぜそうなのでしょうか?聞かない方がいいでしょう。これらの矛盾は、古い時代から来ており、「スマート」なロジックではありません。
現在のスクロールを取得
DOM要素には、その scrollLeft/scrollTop
プロパティに現在のスクロール状態があります。
ドキュメントのスクロールでは、document.documentElement.scrollLeft/scrollTop
はほとんどのブラウザで機能しますが、Safari のような古い WebKit ベースのブラウザ (バグ 5991) を除き、document.documentElement
の代わりに document.body
を使用する必要があります。
幸いなことに、スクロールは特別なプロパティ window.pageXOffset/pageYOffset
で利用できるため、これらの特殊性をまったく覚える必要はありません。
alert('Current scroll from the top: ' + window.pageYOffset);
alert('Current scroll from the left: ' + window.pageXOffset);
これらのプロパティは読み取り専用です。
window
プロパティ scrollX
および scrollY
としても利用可能です。歴史的な理由により、両方のプロパティが存在しますが、それらは同じです。
window.pageXOffset
はwindow.scrollX
のエイリアスです。window.pageYOffset
はwindow.scrollY
のエイリアスです。
スクロール: scrollTo, scrollBy, scrollIntoView
JavaScript でページをスクロールするには、その DOM が完全に構築されている必要があります。
たとえば、<head>
のスクリプトでページをスクロールしようとしても、うまくいきません。
通常の要素は、scrollTop/scrollLeft
を変更することでスクロールできます。
document.documentElement.scrollTop/scrollLeft
を使用してページでも同じことができます (Safari を除く。代わりに document.body.scrollTop/Left
を使用する必要があります)。
または、よりシンプルでユニバーサルなソリューションがあります。特別なメソッド window.scrollBy(x,y) および window.scrollTo(pageX,pageY) です。
-
メソッド
scrollBy(x,y)
は、ページの *現在の位置からの相対* でページをスクロールします。たとえば、scrollBy(0,10)
はページを10px
下にスクロールします。下のボタンでこれをデモします。
-
メソッド
scrollTo(pageX,pageY)
は、ページを *絶対座標* にスクロールし、可視部分の左上隅が、ドキュメントの左上隅に対する座標(pageX, pageY)
を持つようにします。これは、scrollLeft/scrollTop
を設定するようなものです。先頭にスクロールするには、
scrollTo(0,0)
を使用できます。
これらのメソッドはすべてのブラウザで同じように機能します。
scrollIntoView
完全を期すために、もう1つのメソッドについて説明しましょう: elem.scrollIntoView(top)。
elem.scrollIntoView(top)
の呼び出しは、elem
が表示されるようにページをスクロールします。これには1つの引数があります。
top=true
の場合 (これがデフォルトです)、ページはelem
がウィンドウの上部に表示されるようにスクロールされます。要素の上端がウィンドウの上部に揃えられます。top=false
の場合、ページはelem
が下部に表示されるようにスクロールされます。要素の下端がウィンドウの下部に揃えられます。
下のボタンは、ウィンドウの上部に自身を配置するためにページをスクロールします。
そして、このボタンは、ウィンドウの下部に自身を配置するためにページをスクロールします。
スクロールの禁止
ドキュメントを「スクロール不可」にする必要がある場合があります。たとえば、すぐに注意を必要とする大きなメッセージでページを覆い、訪問者にドキュメントではなくそのメッセージを操作させたい場合などです。
ドキュメントをスクロール不可にするには、document.body.style.overflow = "hidden"
を設定するだけで十分です。ページは現在のスクロール位置で「フリーズ」します。
試してみてください。
最初のボタンはスクロールをフリーズし、2番目のボタンはそれを解除します。
document.body
だけでなく、他の要素のスクロールをフリーズするために同じ手法を使用できます。
この方法の欠点は、スクロールバーが消えることです。スクロールバーがいくらかのスペースを占めていた場合、そのスペースが解放され、コンテンツがそれを埋めるために「ジャンプ」します。
それは少し奇妙に見えますが、フリーズ前後の clientWidth
を比較すれば回避できます。増加した場合(スクロールバーが消えた)、コンテンツ幅を同じに保つために、スクロールバーの代わりに document.body
に padding
を追加します。
まとめ
ジオメトリ
-
ドキュメントの可視部分の幅/高さ (コンテンツ領域の幅/高さ):
document.documentElement.clientWidth/clientHeight
-
スクロールアウトした部分を含むドキュメント全体の幅/高さ
let scrollHeight = Math.max( document.body.scrollHeight, document.documentElement.scrollHeight, document.body.offsetHeight, document.documentElement.offsetHeight, document.body.clientHeight, document.documentElement.clientHeight );
スクロール
-
現在のスクロールを読み取る:
window.pageYOffset/pageXOffset
。 -
現在のスクロールを変更する
window.scrollTo(pageX,pageY)
– 絶対座標、window.scrollBy(x,y)
– 現在の位置からの相対的なスクロール、elem.scrollIntoView(top)
–elem
が表示されるようにスクロール (ウィンドウの上/下に合わせる)。
コメント
<code>
タグを使用し、数行の場合は<pre>
タグでラップし、10行以上場合はサンドボックス (plnkr, jsbin, codepen…) を使用してください。