スポンサーリンク

WordPress無料テーマLightningのスクロール時サイドバー固定方法を変更する

Web系

この記事はLightning Ver 6.16.0時点の仕様を元に記述しています。アップデートにより仕様が変わる可能性があります。


WordPressの無料テーマであるLightningには、サイドバーに配置されたメニューやウィジェットが、スクロール時に上部で固定される機能が標準で付いています。

ただ、スクロール時に若干ガタつくのと、固定される位置がページ上の端(CSSのtopプロパティで0pxの位置)であるために一部がヘッダーに隠れてしまうところが気になります。ちなみに前者は、スクロール時にリアルタイムで座標を計算し、CSSを設定していることによって起きているようです。

よって、自分で固定方法を変えてみることにしました。これに伴い、標準の固定機能はテーマカスマイザーより無効にしておきます。

仕様

ページのスクロール時に、サイドバーがヘッダーの下に隠れる直前で、サイドバーのpositionをfixedにします。しかし、単にそれだけだとX座標と幅が崩れるので、ページ表示時にそれらを取得しておき、fixed時に適用します。

また、サイドバーが表示される画面幅の時だけ実行します。

ソースコード

外部のスクリプトファイルとして用意し、functions.phpでwp_footer()内、つまり</body>直前に読み込みます。※勿論、子テーマを用意します

fixside.js

var sidebar,     sidebarRect, siderbarLeft, sidebarDefTop,     sidebarWidth,     slide,     scrollY,     changeStyleCount = 0;  if (window.parent.screen.width> 991 ) {

  window.addEventListener('load', function() {

    sidebar = document.querySelector('.sideSection');
    sidebarRect = sidebar.getBoundingClientRect();
    siderbarLeft = sidebarRect.left;  // サイドバーの初期X座標
    sidebarDefTop = sidebarRect.top;  // サイドバーの初期Y座標
    sidebarWidth = sidebar.clientWidth; // サイドバーの幅

    scrollY = window.pageYOffset ;  // ウィンドウの縦スクロール量
    if (scrollY > 0) {
      /* スクロールした状態でリロードされると初期スクロール量が0より大きくなるので
      マイナスになっているサイドバーの初期Y座標にスクロール量を加算して補正する */
      sidebarDefTop = sidebarDefTop + scrollY;
    }
  })

  window.addEventListener('scroll', function () {

    let header, headerHeight;

    header = document.querySelector('.siteHeader');
    headerHeight = header.clientHeight;  // ヘッダーの高さ ※スクロール時に高さが変化する仕様への対応
    scrollY = window.pageYOffset ;  // ウィンドウの縦スクロール量

    if (sidebarDefTop  2)) {
        countChangeStyle();
        sidebar.style.position = 'fixed';
        sidebar.style.top = headerHeight + 'px';
        sidebar.style.left = siderbarLeft + 'px';
        sidebar.style.marginLeft = '0px';
        sidebar.style.marginTop = '0px';
        sidebar.style.width = sidebarWidth + 'px';
      }
    } else {
      if (sidebar.style != null) {
        if (sidebar.style.position == 'fixed'
          && (changeStyleCount == 0 || changeStyleCount > 2)) {
          sidebar.style.position = 'static';
          sidebar.style.top = '';
          sidebar.style.left = '';
          sidebar.style.marginLeft = '';
          sidebar.style.marginTop = '0px';
          sidebar.style.width = '';
        }
      }
    }
  });
}

/* スタイルが変化した際に時間の経過を計る */
var countChangeStyle = function(){
  changeStyleCount++;
  var id = setTimeout(countChangeStyle, 100);
  if (changeStyleCount >= 5) {
    changeStyleCount = 0;
    clearTimeout(id);
  }
}

スタイルをfixedに変えた際にタイマーで時間を計っているのは、特定条件下においてスタイルの切り替えが連続かつ永遠と続くことにより、ページがスクロール出来ない現象に見舞われたことへ対応となります。

functions.php

function fixside_scripts() {
  wp_enqueue_script( 
    'fixside-script', 
    get_stylesheet_directory_uri() . '/js/fixside.js',
    array('lightning-js'),
    false,
    true
  );
}
add_action( 'wp_enqueue_scripts', 'fixside_scripts' );

Lightning本体のJSによる固定処理を上書きする為に、標準で読み込まれるJSファイルの後に読み込むよう、指定しています。