2011/09/29

要素をスクロールしても画面上部にひっつかせる

・・・とタイトルに書いたがなんのことか全くわからないと思われる。このブログをスクロールしたときに画面一番上にヘッダーが固定されているのが分かると思うが、基本的にはそれと同じことをしたい。

ヘッダーだけを固定化するのであれば、CSSでposition:fixed;にすればいいのだが、(対応していないブラウザの人は我慢してもらう)次のような場合はどうだろう。

最初は画面右側(最上部ではない)にナビゲーションメニュー的な状態で表示されている。
下にスクロールしていくと、このメニューは徐々に画面上、上に動く。要するに普通の文字列と同じように動く。
が、画面の最上部に達すると、
というように画面最上部で静止し、その後はいくらスクロールしても動かない・・・
といったヤツ。

名前は知らないが最近よくみる仕組み。

実際にやってみる

さて、これをCSSとJavaScriptで実現したい。

目標は
ヘッダー直下にメニューが存在して、メニューが隠れる寸前までは通常の文字列と同様にスクロールする。メニューが画面上部に接したらば画面の右上にメニューが据え置きされる。

まずは、対象のブロックのidをmenuとでもしておくと、
#menu{
   position:fixed;
   right:0px;
   top:**px;
}
で右側によってくれる。

topの初期値?

今回はtopの値を固定化している。本当はこの初期値も取得できれば良いのだが、なかなか奥が深く自分はまだ理解に至っていない。それに関する(と思われる)議論は以下のページが詳しい(のだと思う・・なんせ理解していないので)
http://d.hatena.ne.jp/elm200/20080203/1202009300

なので、ここでは簡単にするためにヘッダーの高さheightを一定に固定し、初期状態ではその直下に目的のメニューを配置するに至っている。

スクロールした時のイベント

window.onscroll = function(){
   if((topPos=height-window.scrollY)<0){topPos=0;}
   document.getElementById("main").style.top=topPos;
}
で良かろう。heightはヘッダーの高さを入れる。面白い動きをさせて「おー」と言いたいだけなのでブラウザごとの対応など全く考える気はないが、多分たいていのブラウザで動作する。

まず、スクロールのイベントはwindow.onscrollでいい。

10px下にスクロールしたときは、mainは実質、上に10px動けばいいのだから[元の位置=height]-[スクロール量]が移動後の位置(topの値)。

ただ、これは負のときは画面上部に据え置きにする約束なので、ifで0になるようにしておく。

ということで、完成品

CSS
メニュー本体

position:fixed; right:0px; top:[height]px;
ヘッダー
height:[height]px;
JavaScript
if((topPos=[height]-window.scrollY)<0){topPos=0;}document.getElementById([menu]).style.top=topPos;

height: ヘッダーの高さ
menu:メニューのID

0 件のコメント:

コメントを投稿