カテゴリー
CSS jQuery PHP Webサイト作成 WordPress

スクロール時にナビゲーションメニューを固定する

先日私が管理している別のサイトでトップページの「ヒーローヘッダーの背景画像を固定する」という修正を行いました。

続けて各ページの上部に表示されるナビゲーションメニューの固定にトライしたので、その備忘録を残します。

目標は、スクロールによってナビゲーションメニューが表示エリアのトップに到達すると、ナビゲーションメニューをその位置に固定する、です。もちろん逆パターンにも対応します。

スクロール量の取得にはJavaScript(jQuery)が必要ということで、私のjQueryデビューとなりました。

目次 [閉じる]
  1. jQueryコードの作成
  2. jQueryファイルの読み込み
  3. CSSの設定
  4. 動作確認

1. jQueryコードの作成

今回作成したjQueryコードは下記のようになります。

//
// スクロール時ナビゲーションメニューを固定する
//
jQuery(function() {
    var _window = jQuery(window),
	_body = jQuery('body'),
    	_nav = jQuery('.mynav'),
	navTop = _nav.offset().top,
	navHeight = _nav.outerHeight();

    _window.on('load scroll', function() {
    	if(_window.scrollTop() > navTop) {
    	    if (_nav.hasClass('fixed') != true) {
		_nav.addClass('fixed');
		_body.css('margin-top', navHeight);  
	    } 
    	} else {
    	    if (_nav.hasClass('fixed') == true) {
	       	_nav.removeClass('fixed');   
		_body.css('margin-top', '0');   
	    }
    	}
    });	
});

始めの方に”jQuery(function(){})”とか”jQuery(window)”のように頭に”jQuery”が付いた記述があります。色々なWebサイトでjQueryのコードを見ると、接頭語が”jQuery”ではなく”$”となっていることが多いですが、WordPress環境では”jQuery”にする必要があります。

“jQuery(function(){})”はjQueryであることを示し、それ以外はセレクタ(HTMLのタグやid、class)を指定してオブジェクトを取得するための接頭語だと理解しています。

では、コードの内容を説明します。

まず変数定義の部分では、下記のオブジェクトの割り当て、値の代入を行っています。

  • _window:Windowオブジェクト
  • _body:bodyオブジェクト(<body>~</body>まで)
  • _nav:classが”mynav”であるオブジェクト(ナビゲーションメニュー)
  • navTop:ナビゲーションメニューのトップのY座標値
  • navHeight:ナビゲーションメニューの高さ

_window.on()内の処理は第1引数(‘load scroll’)によりスクロールが行われた際に呼び出されます。今回はページのロードも条件に加えています。

処理としては、_window.scrollTop()でスクロール量を取得して、(スクロール量 > navTop)であればナビゲーションメニューを固定し、そうでなければ固定を解除します。

詳細を以下に示します。

スクロール量 > navTop
  • _navにclass “fixed”を追加。
  • _bodyの”margin-top”に”navHeight”をインラインで設定。
  • 上記の処理は_navにclass “fixed”が設定されていない場合のみ実行されます。
スクロール量 <= navTop
  • _navのclass “fixed”を削除。
  • _bodyの”margin-top”に0をインラインで設定。
  • 上記の処理は_navにclass “fixed”が設定されている場合のみ実行されます。

jQueryコードはページのHTMLコード内に埋め込むこともできますが、今回はfixMenuScript.jsというファイルとして保存しました。

2. jQueryファイルの読み込み

1.で作成したjQueryファイル(fixMenuScript.js)を読み込ませるために、functions.phpのスタイルシートや外部フォントを読み込む関数(アクションフック’wp_enqueue_scripts’に追加登録される関数)内に下記のコードを追加します。

    // JavaScript読み込み
    wp_enqueue_script( 
        'fixMenu-script', 
    	get_template_directory_uri() . '/fixMenuScript.js'
    );

スタイルシートや外部フォントを読み込む際は”wp_enqueue_style()”を使いますが、JavaScriptファイルを読み込む場合は”wp_enqueue_script()”を使います。

ここでは、ハンドル名と、JavaScriptファイルのURLを指定しています。

3. CSSの設定

class “fixed”追加時のナビゲーションメニューのCSSを設定します。

.mynav.fixed {
    position: fixed;
    top: 0;
    width: 100%;
    z-index: 10;
}

positionを”fixed”、topを”0″とすることで、ナビゲーションメニューがトップ位置に固定されます。他のコンテンツの上位に表示されるようz-indexに”10″を設定します。

4. 動作確認

1.~3.の設定を行って動作確認を行ったのですが、

  • Firefox:スクロールをすると表示が激しくガタつく
  • Chrome:表示はがたつかないが、ナビゲーションメニューが固定されない

という不具合が発生しました。

ブラウザの開発ツールで確認すると、

  • Firefox:bodyタグの”margin-top”の数値とナビゲーションメニューの”fixed”クラスの表示がチラチラして安定しない(下図赤線部分)
  • Chrome:そもそも”margin-top”が変化せず、”fixed”クラスも表示されない
開発ツールでの確認
開発ツールでの確認

ということがわかりました。

jQueryファイルやスタイルシートを色々いじってみましたが症状は改善しません。しかし、開発ツールのコンソールでjQueryのエラーは表示されていなかったので、使用しているプラグインをひとつずつ停止してみることにしました。

まず最初に試したのがAll in One SEO Pack。SEO対策で広く使用されているプラグインですね。こいつを停止すると、、、

ナビゲーションメニューがきちんと固定されるようになりました!Chromeでも問題なし!意外にあっさり解決。

良かった、良かった。でも原因は不明。All in One SEO Packが悪かったの?ぢゃ、SEO対策はどうしたらええの?となります。

よく分からないのでとりあえずこの状態からAll in One SEO Packを有効に戻してみることにしました。すると、、、

あれ?問題なし!ちゃんと動作してる。

というわけで、不具合の原因はわからないままですが、いったんAll in One SEO Packを停止して再度有効化すると解消しました。これってよくわからない不具合を解決するための常とう手段でしょうか?

以上、スクロール時にナビゲーションメニューを固定する方法の備忘録でした。

最後までお読みいただきありがとうございました。