ロゴを位置固定にして、スクロールについてくるようにした。あまりスクロールしておらずナビゲーションがまだ見えている場合は、今まで通りウェブサイトのホームへ移動する。変わって、スクロールしてナビゲーションが見えなくなっていると、ページの最上部に移動する、いわゆる「トップヘモドル」ボタンに変わる。
var globalHeader = document.querySelector('.global-header');
var logo = globalHeader.querySelector('.logo');
var siteNavigation = globalHeader.querySelector('.site-navigation');
var scrollToTop = function (evt) {
window.scrollTo(0, 0);
evt.preventDefault();
};
var toggleLogoAction = function (evt) {
if (window.pageYOffset > globalHeader.offsetTop + siteNavigation.scrollHeight) {
logo.addEventListener('click', scrollToTop, false);
return;
}
logo.removeEventListener('click', scrollToTop, false);
};
window.addEventListener('scroll', toggleLogoAction, false);
スクロール・イベントでwindow.pageYOffset
とglobalHeader.offsetTop + siteNavigation.scrollHeight
を比べて、前者が大きい場合はナビゲーションが見えないだろうと推測して、トップヘモドル機能をロゴに割り当てるというシンプルなものだ。トップへモドル機能は単純にリンク先を#top
に書きかえるだけでも良かったが、URLの分散と履歴の汚染をもたらしてしまうのでwindow.scrollTo(0, 0)
を使った。
実際にはいわゆるdebounceで遅延させて、イベントを間引いてたりもしている。スクロール・イベントで何かする場合にdebounceを使うとカクつくため、間引きつつ定期的に発火できるthrottleを使うことが多い。しかし、こういう目に見える変化をもたらさないものならdebounceの方が効率的だろう。
また、再読み込み時などにスクロール・イベントなしでナビゲーションが見えない状態になっている場合を考慮して、最初に一回だけ機能の割り当てを試みるようにもした。その後、スクロールごとにaddEventListener()
を繰り返し行う実装になっており無駄が多いが、同じものは複数割り当てられることはないので、わざわざフラグ管理などをしなくても悪くはない(良くはない)。
他にはリンクのhref
属性の値を#top
に書きかえ、ページを遷移するリンクではないことがわかるようにもしておいた。実際には#top
に移動するわけではない上、現状のブラウザーの実装だと#
以降が見えないこともあるので、完璧な解ではない。とは言っても、少なくともページを遷移するように見えるリンクのままよりは良いだろうし、機能的にはほぼ同等なので及第点と考えた。
これはイメージとしては最近色々言われることの多いハンバーガー・ボタンによるナビゲーションの展開のごくシンプルな変種というと近い。ページの最上部へ戻らせることではなく、トップにあるナビゲーションを表示させることを目的としてる。
欠点は、どうあがいても結局のところ「トップヘモドル」ボタンのため、押した時点で今まで読んでいたところに戻る手段がないことだ。ナビゲーションも位置固定にして、スクロールと同時に隠し、ロゴを押すと展開されるといった形にすると解決するが、Homeキーを押すのと同じと考えると、それほど気にするほどのことでもないだろう。
もうひとつの欠点はウェブサイトのホームへ移動する方法がわかりづらくなることだ。これはロゴからハンバーガーのアイコンに変更するなどして、画像でそれぞれの機能を示せば良いかもしれない。しかし、そうなると別にハンバーガー・ボタンを配置した方が明らかに効率的になるので、微妙なところだ。
Internet Explorer 8以下への対応などを除いたとしてもいくつかの欠点があるものの、ナビゲーションへの簡単なアクセスを可能にする方法としては、シンプルで悪くないアプローチではあるとは言える。少なくとも「トップ」が何を指しているのかよくわからない「トップヘモドル」ボタンをそのまま設置したり、そこかしこに#top
を使ったリンクを張るよりは随分とマシであるはずだ。