Bootstrap で .navbar-fixed-top を使用している時に #anchor がずれてしまう問題の対応


Twitter Bootstrap v2.1.1 で固定ナビゲーションバー(※)を使うと、#anchor でページ内の特定の位置に移動した時に一部のコンテンツがナビゲーションバーに隠れてしまう。

※ 固定ナビゲーションバー
.navbar-fixed-topで指定。ページをスクロールしてもナビゲーションバーだけがウィンドウの一番上に固定で残る表示。

ブラウザの動作としては、そのコンテンツをウィンドウの上端まで移動しているので、当たり前と言えば当たり前だが、これは困る。ので JavaScript を追加して対応してみました。

(対応にあたって色々検索してみたら同じように困っている人が結構いたので、そのうち Bootstrap 本体の方で改善されるかもしれません。この記事が古くなっていた場合は先にご確認をお願いします。)

2箇所で対応

ポイントは2か所あり、ページ内目次などのアンカーがクリックされた場合と、URLにの末尾に #anchor を付けてアクセスされた場合の2方面で行います。

ページ内の移動時の対応

ページ内でのクリックに対応する場合、リンクの方にスクロール動作をバインドしておく。
こんな感じです。

<script>
$(document).ready(function(){
//(色々)
$(‘#pageindex a[href^=”#”]’).click(function(){
if($(document).width()>768){
$(document).scrollTop(($(‘#’+this.href.replace(/.*#/, “”)).offset().top) – $(“.navbar-fixed-top”).height());
return false;
} else {
return true;
}
});
});
</script>

外部からの #anchor 付アクセスに対応

外部から直接 #anchor 付でアクセスされる場合の対応は、ページロード時にURLにアンカーがあるかないかをチェックしてスクロール。

<script>
$(document).ready(function(){
//(色々)
var indexPound = document.URL.lastIndexOf(“#”);
if(0 < indexPound && indexPound < document.URL.length-1 && $(document).width()>768){
var AncRegexp = new RegExp(“#(.+)$”, “”);
document.URL.match(AncRegexp);
var Anc = RegExp.$1;
$(‘html, body’).animate({
scrollTop: ($(‘#’+Anc).offset().top) – $(“.navbar-fixed-top”).height(),
}, {}
)
}
});
</script>

実装したサイト

http://multilingual-editor.sugutsukaeru.jp/ja/manual.html#character_reference

外部ファイルにスクリプトを分けているので、直接アクセスの場合にスクリプトのロードが遅れるとうまくいっていないですね。その点要改善。