トップヘモドル機能付きの位置固定なロゴ

ロゴを位置固定にして、スクロールについてくるようにした。あまりスクロールしておらずナビゲーションがまだ見えている場合は、今まで通りウェブサイトのホームへ移動する。変わって、スクロールしてナビゲーションが見えなくなっていると、ページの最上部に移動する、いわゆる「トップヘモドル」ボタンに変わる。

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.pageYOffsetglobalHeader.offsetTop + siteNavigation.scrollHeightを比べて、前者が大きい場合はナビゲーションが見えないだろうと推測して、トップヘモドル機能をロゴに割り当てるというシンプルなものだ。トップへモドル機能は単純にリンク先を#topに書きかえるだけでも良かったが、URLの分散と履歴の汚染をもたらしてしまうのでwindow.scrollTo(0, 0)を使った。

実際にはいわゆるdebounceで遅延させて、イベントを間引いてたりもしている。スクロール・イベントで何かする場合にdebounceを使うとカクつくため、間引きつつ定期的に発火できるthrottleを使うことが多い。しかし、こういう目に見える変化をもたらさないものならdebounceの方が効率的だろう。

また、再読み込み時などにスクロール・イベントなしでナビゲーションが見えない状態になっている場合を考慮して、最初に一回だけ機能の割り当てを試みるようにもした。その後、スクロールごとにaddEventListener()を繰り返し行う実装になっており無駄が多いが、同じものは複数割り当てられることはないので、わざわざフラグ管理などをしなくても悪くはない(良くはない)。

他にはリンクのhref属性の値を#topに書きかえ、ページを遷移するリンクではないことがわかるようにもしておいた。実際には#topに移動するわけではない上、現状のブラウザーの実装だと#以降が見えないこともあるので、完璧な解ではない。とは言っても、少なくともページを遷移するように見えるリンクのままよりは良いだろうし、機能的にはほぼ同等なので及第点と考えた。


これはイメージとしては最近色々言われることの多いハンバーガー・ボタンによるナビゲーションの展開のごくシンプルな変種というと近い。ページの最上部へ戻らせることではなく、トップにあるナビゲーションを表示させることを目的としてる。

欠点は、どうあがいても結局のところ「トップヘモドル」ボタンのため、押した時点で今まで読んでいたところに戻る手段がないことだ。ナビゲーションも位置固定にして、スクロールと同時に隠し、ロゴを押すと展開されるといった形にすると解決するが、Homeキーを押すのと同じと考えると、それほど気にするほどのことでもないだろう。

もうひとつの欠点はウェブサイトのホームへ移動する方法がわかりづらくなることだ。これはロゴからハンバーガーのアイコンに変更するなどして、画像でそれぞれの機能を示せば良いかもしれない。しかし、そうなると別にハンバーガー・ボタンを配置した方が明らかに効率的になるので、微妙なところだ。

Internet Explorer 8以下への対応などを除いたとしてもいくつかの欠点があるものの、ナビゲーションへの簡単なアクセスを可能にする方法としては、シンプルで悪くないアプローチではあるとは言える。少なくとも「トップ」が何を指しているのかよくわからない「トップヘモドル」ボタンをそのまま設置したり、そこかしこに#topを使ったリンクを張るよりは随分とマシであるはずだ。