【Javascript】対象へ画面をスクロール(備忘録)

【動機】
現在、『jquery.ajaxComboBox.js 3.0』を鋭意制作中です。


その一環で画面のスクロール処理にも若干の修正を加えようと
していたのですが…。
普段僕は、コメントをソース中にしつこいぐらいに挿入して
いるんですが、該当の箇所にはほとんどコメントがなく、
『なんのこっちゃ、わけわからん』状態でした。


ただ、あらためてソースの流れを追ってみると、画面表示と密接に
かかわっている部分だけに、コメントでは端的に説明できないため、
書けなかったのも無理ないなと思いました。


そこで、備忘録として、画面のスクロール処理の流れを
図解で残しておきます。


【使用する変数】

変数名説明
target_top 選択中の項目の、ページ上端からの距離
target_size 選択中の項目の縦のサイズ
client_height ブラウザの縦のサイズ
scroll_top
これを超えたら画面をスクロールさせる、という基準点。
上方向の限界点。
scroll_bottom
これを超えたら画面をスクロールさせる、という基準点。
下方向の限界点。
『scroll_top + client_height - target_size』
で算出される。


【画面スクロールのパターン】
  1. 【スクロールなし】



    状態:
    (target_top >= scroll_top) &&
    (target_top <= scroll_bottom)
  2. 【上へスクロール】



    状態:
    target_top < scroll_top

    スクロール処理:
    window.scrollBy(0, (target_top - scroll_top));

    Y軸において、マイナス方向へスクロールすることになります。
  3. 【下へスクロール】



    状態:
    target_top > scroll_bottom

    スクロール処理:
    window.scrollBy(0, (target_top - scroll_bottom));

    Y軸において、プラス方向へスクロールすることになります。
  4. 【例外】



    状態:
    target_size > client_height

    スクロール処理:
    window.scrollBy(0, (target_top - scroll_top));

    ブラウザの高さがターゲットの高さよりも低いという

    例外的な状況では、ターゲットの上端をブラウザの上端にそろえて、

    見栄えを保ちます。


【コード全体】
※実際のプラグインのコードとは若干異なります。


なお、ブラウザの高さや、ページ上端からの距離の取得の
処理部分の詳しい説明は、下記をご覧ください。

【Javascript】ブラウザの表示領域サイズ取得について


//-------------------------------------------
//使用する変数を設定
//-------------------------------------------
//『$current』には、現在行の<li>要素が入っています。
var target_top = $current.offset().top;

var target_size =
$current.height() +
parseInt($current.css('border-top-width'), 10) +
parseInt($current.css('border-bottom-width'), 10) +
parseInt($current.css('padding-top'), 10) +
parseInt($current.css('padding-bottom'), 10);

var client_height = document.documentElement.clientHeight;

var scroll_top = (document.documentElement.scrollTop > 0)
? document.documentElement.scrollTop
: document.body.scrollTop;

var scroll_bottom = scroll_top + client_height - target_size;


//-------------------------------------------
//スクロール処理
//-------------------------------------------
if(target_top < scroll_top || target_size > client_height) {
//ブラウザ上端へスクロール
window.scrollBy(0, (target_top - scroll_top));

} else if (target_top > scroll_bottom) {
//下へスクロール
window.scrollBy(0, (target_top - scroll_bottom));

} else {
//スクロールは行われない
return;
}