レイヤーの位置をウィンドウ内で特定の位置に保つことが出来ます。
スクロールが行われる度に
現在のスクロール位置、Windowサイズからレイヤーのあるべき座標(x,y)を
計算し移動します。
WinIEではonscrollハンドラを利用できますがそれ以外では
50msec毎に位置を再計算します。
【レイヤーを右上に位置固定するサンプル】
<script language="javascript" src="http://www.keynavi.net/files/keynavi_ja.js"></script>
<script language="javascript" src="http://www.keynavi.net/files/keynavi_tools.js"></script>
<script language="javascript"><!--
//kl_onload_ex()は定義しておくとonLoad時に自動で呼ばれます//
function kl_onload_ex(){
//レイヤーを表示します//
kl_layer_show("mylay1");
//レイヤー「mylay1」をウィンドウ内の右上に配置します//
kl_layer_setpos("mylay1","right_top");
//WinIEではonscrollハンドラが使えるので登録します//
if(KL_IE4W) kl_addhandler(window,"onscroll","MyFunc");
//それ以外のブラウザではsetInterval()で50msec毎にMyFunc()を実行//
else setInterval("MyFunc()",50);
//ウィンドウのサイズ変更時にも再配置します//
kl_addhandler(window,"onresize","MyFunc");
return true;
}
function MyFunc(){
//レイヤー「mylay1」をウィンドウ内の右上(right_top)に配置します//
//例えば真ん中にするには引数を"center"とします//
kl_layer_setpos("mylay1","right_top");
}
//-->
</script>
<!--右上に位置固定されるレイヤーです-->
<div style="position:absolute; ..." id="mylay1">Hello World!</div>
Hello World!
ユーザビリティーの視点
上記のコードによりレイヤーを簡単に特定位置に固定できますが
この方法には問題があります。
実際にこのページでも実験できますが
スクロール時にレイヤーが「カクカク」微小移動します。
下へスクロールすると固定したレイヤーが本文と一緒に一瞬上に移動し
直後に固定した位置に復帰します。これが連続的に多数回発生します。
その結果レイヤーがちらつくため ユーザの注意がそらされされます。
マシン負荷
WinIE以外のブラウザではonscrollハンドラが使えないので
50msec毎に位置を再計算しています。
ページを見ていないときでも実行されるためマシン負荷がかかります。
タスクマネージャで見ると特にOpera7.0ではCPU使用率が跳ね上がり
数パーセント〜10パーセントになっています。
ブラウザに表示されているだけで常時これだけ消費してしまいます。
Netscape4,6では1パーセント以下の模様。
対策私案
対策として フレームを使うことができます。
またNetscape6.1+,Mozilla,Opera6+ではスタイルシートで「position:fixed」として
位置を固定できます。しかしIE4-6,Netscape4.xではダメです。
他の方法としては
body要素に対し「background-attachment:fixed;」として
背景画像を固定できます(IE4-6,Netscape6+,Mozilla,Opera6+)。
これらではスクロール時に微小移動する問題は無いです。
背景画像を使った場合、対象Objectは背景なのでリンクを置くことが出来ません。
そこでリンク指定した透明GIFを位置固定レイヤー内におき
固定背景部分に重ねてはどうでしょうか?
透明画像は見えないので見かけ上 デザインは微小移動せずキチンと固定され
リンクボタンも一緒に動作させることが出来ます。
上の例ではできるだけレイヤー位置を変えないためMyFunc()の実行間隔が
「50msec」でしたが 透明画像なら見栄えに問題が無いため
「500msec」などずっと大きめの値でOKだと思われます。
リンククリックの前には マウス操作があるため「onmousemove,onmousedown」、
「フォーカス移動+リターン」では「onkeydown,onkeyup」イベントが起こるはずなので
このタイミングのみにMyFunc()を実行するのもうまい方法です。
背景画像として表示する内容を動的に変えたい場合は
レイヤーの背景画像を指定:kl_layer_setbgimage(id,...)
や 動的にレイヤーの中身を書き替え&URLロード:kl_layer_write/load()
が使えます。
おまけ
(2003/10/11: kl_alert_xxx廃止、keynavi_demo.jsへ移行)
ところで
KeyNaviの使い方レイヤー「Shift-X」では位置を中心に保っています。
呼出回数の多い「onscroll」を使わず キーを押し上げた「onkeyup」時にのみ
レイヤー位置を中心に移動しています。
これでも「カクカク」感が強いですね。そのうち方法を変えるかも。
「D/K」や「矢印キー」を押してスクロールしている時には
レイヤーは普通にスクロールされます。キーを上げた時に真ん中に表示されます。
【kl_alert_xxx向けkeyupハンドラとその登録(抜粋)<keynavi_tools.js】
function kl_alert_onkeyup(){
kl_alert_centralize();
return true;
}
function kl_alert_setup(){
。。。。。
kl_addhandler_ex("onkeyup", kl_alert_onkeyup);
。。。。。
}
注:上の実装例ではKeyNavi拡張APIを利用しています。