はてなブログでスクロールすると画面上部に固定されるPC・スマホ両方に対応したグローバルメニューを表示する方法(PC・スマホ両方に対応)の改良版
以前作ったこちらの画面をスクロールした時に追従するグローバルメニューですが、細かいところで何か所か修正したので別記事で公開します。
修正した点
修正した点ですが、画面を縦にスクロールしグローバルメニューが追従し出すところで、画面が少し上に動いてしまい、大変気持ち悪かったので調整しました。
もう一点はものすごく細かいですが、スマホのはてブロのメニューの横にアイコンを出したかったのですが、前回紹介したWEBフォント Font Awesome には無く、あきらめていたのですが、表示する方法があったので、そちらを表示するようにしました。
もう一つもものすごく小さいことですが、追従するグローバルメニューが背景と同化しすぎているように見えたので、少し影を付けました。
まずはグローバルメニューの切り替え時の調整
PC版とスマホ版でグローバルメニューの高さが違うため、それぞれ調整が必要となります。
PC版のグローバルメニューを追従する境目での調整
グローバルメニューを追従する境目での調整のうちPC版の調整ですが、グローバルメニューをposition: fixed;とすると、グローバルメニューの縦幅だけ画面が上に詰まってしまうため、いきなり画面が上に動くように見えていたのが原因でした。
色々と世の中のグローバルメニューを固定する方法のデモを見て調べてやっと見つけることができました。
下の画像を見ると分かると思いますが、確かに高さが違います。
グローバルメニューがある場合
グローバルメニューが無い場合
ダミーの要素を追加して調整
このため、グローバルメニューをposition: fixed;にする際にグローバルメニューが元々あった場所にグローバルメニューと同じ高さの要素を追加するようにして対応しました。
スマホ版のグローバルメニューを追従する境目での調整
グローバルメニューを追従する境目での調整のうちスマホ版の調整はPC版の調整にプラスして、元々の固定表示の際のグローバルメニューと追従するグローバルメニューの高さが違うので、グローバルメニューを切り替える位置の調整が必要となりました。
下の画像を見ていただくと分かると思いますが、かなり高さが違います。
固定のグローバルメニュー
追従するグローバルメニュー
切り替えを開始する位置を変えて調整
position: fixed;に切り替える位置の調整ですが、下の式で切り替え位置が求められます。
固定のグローバルメニューの上の位置
+ 固定のグローバルメニューの縦幅
- 追従するグローバルメニューの縦幅
そして、この位置を画面が過ぎたらPC版と同様に固定のグローバルメニューと縦幅が同じダミーの要素を入れることでスクロールしても違和感がなくなります。
はてなブログのアイコンの表示
はてなブログのアイコンですが、はてなブログの場合なら表示できるWEBフォントにあったので、そちらを表示するようにしました。
こちらの記事に利用できるアイコンの一覧が載っています。
こちらのブログの記事にも書いてありますが、はてなブログの公式ページには書かれていないようです。
アイコンを出した見た目はこんな感じです。
最終的なjavascriptはこんな感じになりました。
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
$(document).ready(function(){
// グローバルメニュー表示
//ダミーのヘッダー要素
var takasatyousei = '<div id=takasatyousei><div>'
//固定用のヘッダー
var title = '<div class="globalmenu" id="staticmenu"><nav class="globalnavi"><ul><li><a href="/archive">記事一覧</a></li>';
var categoryobj = $("#box2-inner").find(".hatena-module-category li");
var categorycount = categoryobj.length;
for (var i=0; i< categorycount; i++) {
var category = categoryobj.eq(i).find('a');
title = title + '<li><a href="' + category.attr("href") + '">' + category.text() + '</a></li>';
if(i > 3){
break;
}
}
title = title + '</ul></nav><div>';
//スマホ画面移動時のヘッダー
sp_title = '<div class="globalmenu hide" id="fixmenu"><nav class="globalnavi"><ul><li><a href="/archive/category/自転車屋"><i class="fa fa-bicycle"></i>自転車屋</a></li><li><a href="/archive/category/お酒"><i class="fa fa-beer"></i>お酒</a></li><li><a href="/archive/category/はてブロ改造"><i class="blogicon-hatenablog"></i>はてブロ</a></li></ul></nav><div>';
//初期値設定
$("#blog-title").after(takasatyousei + title + sp_title);
//グローバルメニューを取得
var takasatyousei = $('#takasatyousei');
var globalstaticmenu = $('#staticmenu');
var globalfixmenu = $('#fixmenu');
var menu = "static";
//固定のグローバルメニューの位置(高さ)を取得
var sTop = globalstaticmenu.offset().top;
//固定のグローバルメニューの幅(高さを取得)
var sHeight = globalstaticmenu.height();
//追従するグローバルメニューの幅(高さを取得)
var fHeight = globalfixmenu.height();
//画面がスクロールされたときに起きるjQueryのイベント
$(window).scroll(function () {
var windowwidth = $(this).width();
var menuposition = $(this).scrollTop();
//スマホ
if(windowwidth < 480 && menuposition > sTop + sHeight - fHeight) {
if(menu == "static"){
globalfixmenu.removeClass('hide').addClass('fixed');
menu = "fix";
}
//PC
}else if(windowwidth >= 480 && menuposition > sTop){
if(menu == "static"){
takasatyousei.css("margin-top", sHeight+ "px");//ヘッダーの高さ分だけ詰まってしまうのを防ぐため、ダミーのヘッダーを表示
globalstaticmenu.removeClass('hide').addClass('fixed');
menu = "fix";
}
//menuを移動
}else if(menu == "fix"){
takasatyousei.css("margin-top", "0");
//グローバルメニューを元の位置に固定
globalstaticmenu.removeClass('fixed').removeClass('hide');
globalfixmenu.removeClass('fixed').addClass('hide');
menu = "static";
}
});
});
CSSのコードはこちらになります。
/*グローバルメニュー調整*/
.globalmenu {
z-index: 9000;
background:#ebe9e3;
left:0px;
width:100%;
}
.globalnavi ul{
font-size: 1.4em;
list-style: none;
text-align: center;
margin:0;
padding: 0;
}
.globalnavi ul li{display: inline-block;}
.globalnavi ul li a{
text-decoration: none;
display: block;
padding: 10px;
}
/*スマホ用のグローバルメニュー調整*/
@media screen and (max-width: 480px) {
.globalnavi ul li a{padding: 5px;}
}
.hide {
display: none;
}
.fixed {
position: fixed;
top:0px;
box-shadow: 0 5px 5px rgba(0, 0, 0, 0.2);
}
動きも滑らかで