気楽に生きよう!

うつ病、野球、エンタメ 色々喋るよ

レスポンシブに対応したサイドバー複数固定改善版(はてなブログ向け)

f:id:nuruta:20170312013233j:plain
はてなブログカスタマイズの記事です。
シロマティ (id:shiromatakumi)さんのコードを借用しています。

はじめに

このプログラムは、シロマティ (id:shiromatakumi)さんが作られたコードを元に改造しています。

先ずは、こちらの記事をよくお読みの上、当カスタマイズを行うようにして下さい。
f:id:nuruta:20161128225613j:plain

サイドバーの複数固定をやりたかった

nuruta.hatenablog.com
以前は2コンテンツとタブ化されたコンテンツの2種類のカスタマイズ方法を書きました。
その後、僕のメインブログを弄っていくうちに、これだとちゃんとした動作をしてくれなくなりました。

現在、タグメニューを表示させているのですが、こいつの(縦の)長さがクリック1つで変わってしまうことが原因で、タグメニューと動かすサイドバーが重なって表示されてしまうのです。
これはいかんということで改善してみました。

サイドメニューの長さが可変だけれど、特定のコンテンツを追従させたいよって場合の参考にしてみて下さい。
ソースコードだけ公開いたします。

動作環境・注意事項

一応僕の環境では動作確認済みです。

動作確認済み環境
■ブラウザ

  1. GoogleChrome バージョン 54.0.2840.99 m
  2. Internet Explorer11 バージョン 11.0.9600.18524

■デザインテーマ
Brooklyn


必ずバックアップを取った上で、自己責任で行って下さい。
申し訳ございませんが、復旧できなくなった場合の保証は致しません。

基本のき

シロマティ (id:shiromatakumi)さんの記事より引用させて頂きます。

まずは、下記のjQueryの読み込み用のコードを「デザイン」→「カスタマイズ」→「ヘッダー」か「フッター」にコピペします。すでにjQueryの読み込みのコードがある場合は、不要です。
シェア数をカウントしている人はすでに読み込まれてるかと思います。


<!--[if lt IE 9]>
<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.12.3.min.js"></script>
<![endif]-->
<!--[if gte IE 9]><!-->
<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-2.2.3.min.js"></script>
<!--<![endif]-->

可変するコンテンツの中身

僕のブログでは、タグカテゴリメニューが可変します。
そのコードはこちら。

<div class="menu-inner">
    <div id="btn-content">
        <span id="menu-btn"><i class="blogicon-reorder"></i> MENU</span>
    </div>
    <ul class="defaultlist list7">
        <li>
            <label for="Panel1">カテゴリ1      ▼クリックで開閉</label>
            <input type="checkbox" id="Panel1" class="on-off" />
            <ul class="second-content">  
                <li><a href="http://nuruta.hatenablog.com/archive/category/(ここにカテゴリ名)">カテゴリ1-1</a></li>            
                <li><a href="http://nuruta.hatenablog.com/archive/category/(ここにカテゴリ名)">カテゴリ1-2</a></li>  
                <li><a href="http://nuruta.hatenablog.com/archive/category/(ここにカテゴリ名)">カテゴリ1-3</a></li>
            </ul>
        </li>
        <li>
            <label for="Panel12">カテゴリ2     ▼クリックで開閉</label>
            <input type="checkbox" id="Panel12" class="on-off" />
            <ul class="second-content">
                <li><a href="http://nuruta.hatenablog.com/archive/category/(ここにカテゴリ名)">カテゴリ2-1</a></li>
                <li><a href="http://nuruta.hatenablog.com/archive/category/(ここにカテゴリ名)">カテゴリ2-2</a></li>
                <li><a href="http://nuruta.hatenablog.com/archive/category/(ここにカテゴリ名)">カテゴリ2-3</a></li>
            </ul>
        </li>
        <li><a href="http://nuruta.hatenablog.com/archive/category/(ここにカテゴリ名)">カテゴリ3</a></li>
        <li><a href="http://nuruta.hatenablog.com/archive/category/(ここにカテゴリ名)">カテゴリ4</a></li>

カテゴリ1とカテゴリ2がクリックで開閉する仕組みにしています。
それぞれチェックボックスを使っており、idで管理。
CSSを使って見えなくしているという訳です。

今回は、チェックボックスのidをコードで使用しています。

複数コンテンツを固定する

複数のコンテンツを同時に固定する方法です。
次のコードを「デザイン」→「カスタマイズ」→「ヘッダ」か「フッター」にコピペします。

<script>
// ここはユーザーごとで書き換える
var oneColumnWidth = 919;
var fixTop = 50;
var timer = 5000;
var tab0 = 5;
var tab1 = 6;
var tab2 = 7;
var tab3 = 8;


// サイドバーの固定
$(window).load(setTimeout(function (){
	// サイドバーの一番最後のモジュール
	var $module =    $(".hatena-module").filter(function(index){ return index == tab0});
	var $module2 =    $(".hatena-module").filter(function(index){ return index == tab1});
	var $module3 =    $(".hatena-module").filter(function(index){ return index == tab2});
	var $module4 =    $(".hatena-module").filter(function(index){ return index == tab3});
	var $module5 =    $(".hatena-module").filter(":last");

	var modulePosition = $module.offset().top;
	var moduleHeight = $module.outerHeight(true)+fixTop;
	
	// サイドバー全体
	var sidebarHeight = $('#box2').outerHeight();
	var sidebarWidth = $('#box2').width();
	// メインコンテンツ
	var mainHeight = $('#main').outerHeight();

	var flag=true;
        var flag2=true;
	// サイドバーを固定にする関数
	function fixedLastModule(){
		if($('#Panel1').is(':checked')) {
			if (flag){
				modulePosition = $module.offset().top;		
				moduleHeight = $module.outerHeight(true)+fixTop;
				flag=false;
			}
		} else {
			if (!flag){
				modulePosition = $module.offset().top;		
				moduleHeight = $module.outerHeight(true)+fixTop;
				flag=true;
			}
		}

		if($('#Panel12').is(':checked')) {
			if (flag2){
				modulePosition = $module.offset().top;		
				moduleHeight = $module.outerHeight(true)+fixTop;
				flag2=false;
			}
		} else {
			if (!flag2){
				modulePosition = $module.offset().top;		
				moduleHeight = $module.outerHeight(true)+fixTop;
				flag2=true;
			}
		}

		// メインコンテンツよりサイドバーが長い場合は無効化
		if(sidebarHeight > mainHeight){return;}
		
		// 2カラムで、モジュールの一番最後までスクロールされたらCSSの書き換え
		if($(window).outerWidth() > oneColumnWidth && $(window).scrollTop() > modulePosition) {
			$module.css({
				'position': 'fixed',
				'top': fixTop,
				'width': sidebarWidth
			});
			$module2.css({
				'position': 'fixed',
				'top': moduleHeight,
				'width': sidebarWidth
			});
			$module3.css({
				'position': 'fixed',
				'top': moduleHeight,
				'width': sidebarWidth
			});
			$module4.css({
				'position': 'fixed',
				'top': moduleHeight,
				'width': sidebarWidth
			});
			$module5.css({
				'position': 'fixed',
				'top': moduleHeight,
				'width': sidebarWidth
			});
		} else {
           	        $module.css({
				'position': '',
				'top': '',
				'width': ''
			});
			$module2.css({
				'position': '',
				'top': '',
				'width': ''
			});
			$module3.css({
				'position': '',
				'top': '',
				'width': ''
			});
			$module4.css({
				'position': '',
				'top': '',
				'width': ''
			});
			$module5.css({
				'position': '',
				'top': '',
				'width': ''
			});
		}
		// フッターの位置まで来たらストップ
		// 高さの設定
		var bodyHeight = $('body').outerHeight();
		var windowHeight = $(window).outerHeight();
		var footerHeight = $('#footer').outerHeight();
		var scrollBottom = bodyHeight - windowHeight - footerHeight;
		if(moduleHeight  > windowHeight - footerHeight){
			if($(window).outerWidth() > oneColumnWidth && $(window).scrollTop() >= scrollBottom){
				$('#content').css({
					'position': 'relative'
				});
				$module.css({
					'position': 'absolute',
					'top': '',
					'bottom': 0
				});
				$module2.css({
					'position': 'absolute',
					'top': '',
					'bottom': 0
				});
				$module3.css({
					'position': 'absolute',
					'top': '',
					'bottom': 0
				});
				$module4.css({
					'position': 'absolute',
					'top': '',
					'bottom': 0
				});
				$module5.css({
					'position': 'absolute',
					'top': '',
					'bottom': 0
				});
			} else {
				$('#content').css({
					'position': ''
				});
				$module.css({
					'bottom': ''
				});
				$module2.css({
					'bottom': ''
				});
				$module3.css({
					'bottom': ''
				});
				$module4.css({
					'bottom': ''
				});
				$module5.css({
					'bottom': ''
				});
			}
		}
	}
	// イベントの設定
	$(window).scroll(fixedLastModule);
	$('body').on('touchmove', fixedLastModule);
	$(window).resize(fixedLastModule);	
}, timer));
</script>

続いて、コードの中の以下の部分を書き換えていきます。

// タブメニューの番号指定
var tab0 = 5;
var tab1 = 6;
var tab2 = 7;
var tab3 = 8;

僕のブログを例にしますと、サイドバーコンテンツは次のように数字で表わされます。
f:id:nuruta:20161128221433j:plain
一番上のコンテンツを0として、以下1つずつ数字が増えていきます。
動かしたいコンテンツを番号で指定してください。
一番下のコンテンツは自動で動くようになっていますので、無視して下さって構いません。

動かしたいコンテンツを減らしたい場合…例えば、4つのコンテンツの場合は

var tab3 = 8;

var $module4 = $(".hatena-module").filter(function(index){ return index == tab3});

さらに、$module4を使っている箇所を全て削除して下さい。

最後に

正直苦労しました。
なかなか意図した通りに動いてくれなくて。
上手くいったと思ったら、カクカクしたりして。

このまま使える訳ではありませんが、参考になれば幸いです。