Mangaism

アニメ、漫画の感想や考察を書いてます

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

この記事は

最初で最後のはてなブログカスタマイズの記事です。

はじめに

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

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

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

シロマティ (id:shiromatakumi)さんの作られたモノも含め、検索すると「一番下のコンテンツの固定」方法は色々と検索出来たのですが、複数のコンテンツを固定する方法は見つけられませんでした。
僕としては、複数のコンテンツを固定したかったので、今回勝手ながらシロマティ (id:shiromatakumi)さんのコードを借用して作ってみました。
2コンテンツとタブ化されたコンテンツの2種類を作ったので、カスタマイズ方法を書いていきます。
どちらかお好きな方を採用して下さい。
両方同時にとかはやらないで下さいね。動きませんので。
(3コンテンツ以上動かしたい場合はタブ化の方を改造すれば可能だと思いますが、省かせて頂きます。)

動作環境・注意事項

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

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

  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]-->

2つのコンテンツを固定する

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

<script>
// ここはユーザーごとで書き換える
var oneColumnWidth = 919;
var fixTop = 50;
var timer = 5000;

// 下から2番目のコンテンツの指定
var Kotei1 = 9;   

// サイドバーの固定
$(window).load(setTimeout(function (){
	// サイドバーの一番最後のモジュール
	var $module =    $(".hatena-module").filter(function(index){ return index == Kotei1});
	var $module2 =    $(".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();
	// サイドバーを固定にする関数
	function fixedLastModule(){
		// メインコンテンツよりサイドバーが長い場合は無効化
		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
			});
		} else {
			$module.css({
				'position': '',
				'top': '',
				'width': ''
			});
			$module2.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
				});
			} else {
				$('#content').css({
					'position': ''
				});
				$module.css({
					'bottom': ''
				});
				$module2.css({
					'bottom': ''
				});
			}
		}
	}
	// イベントの設定
	$(window).scroll(fixedLastModule);
	$('body').on('touchmove', fixedLastModule);
	$(window).resize(fixedLastModule);	
}, timer));
</script>

コードで書き換える個所は色々あるのですが、それについてはシロマティ (id:shiromatakumi)さんの記事を参照願います。
基本的にはそのままでいいと思いますが、1か所必ず書き換えて頂かなければなりません。

抜粋しますと、

// 下から2番目のコンテンツの指定
var Kotei1 = 8;

この部分です。
この数字「8」が「下から2番目のコンテンツ」を表しています。

僕のブログを例にしますと、サイドバーコンテンツは次のように数字で表わされます。
f:id:nuruta:20161128221433j:plain
一番上のコンテンツを0番目として、下から2番目のコンテンツは「8」という訳です。
ご自身のサイドバーコンテンツの数を数え、下から2番目のコンテンツに符合する数字に書き換えて下さい。

以上で、2つのコンテンツの追従カスタマイズは完了となります。

タブ化されたものを動かす

今現在僕のブログでそうしているのがこれにあたります。
これはid:ftmacchoさんのサイドメニュータブ化カスタマイズをされている方が対象となります。

先ず、タブコンテンツの順番を一番下に持ってきます。
こんな具合です。
f:id:nuruta:20161128221433j:plain
番号で言えば、6番目から9番目がタブメニューですね。

次に下のコードを「デザイン」→「カスタマイズ」→「ヘッダ」か「フッター」にコピペします。

<script>
// ここはユーザーごとで書き換える
var oneColumnWidth = 919;
var fixTop = 50;
var timer = 5000;

// タブメニューの番号指定
var tab0 = 6;
var tab1 = 7;
var tab2 = 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(":last");

	var modulePosition = $module.offset().top;
	var moduleHeight = $module.outerHeight(true)+fixTop;
	
	// サイドバー全体
	var sidebarHeight = $('#box2').outerHeight();
	var sidebarWidth = $('#box2').width();
	// メインコンテンツ
	var mainHeight = $('#main').outerHeight();
	// サイドバーを固定にする関数
	function fixedLastModule(){
		// メインコンテンツよりサイドバーが長い場合は無効化
		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
			});
		} else {
			$module.css({
				'position': '',
				'top': '',
				'width': ''
			});
			$module2.css({
				'position': '',
				'top': '',
				'width': ''
			});
			$module3.css({
				'position': '',
				'top': '',
				'width': ''
			});
			$module4.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
				});
			} else {
				$('#content').css({
					'position': ''
				});
				$module.css({
					'bottom': ''
				});
				$module2.css({
					'bottom': ''
				});
				$module3.css({
					'bottom': ''
				});
				$module4.css({
					'bottom': ''
				});
			}
		}
	}
	// イベントの設定
	$(window).scroll(fixedLastModule);
	$('body').on('touchmove', fixedLastModule);
	$(window).resize(fixedLastModule);	
}, timer));
</script>

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

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

再び僕のブログを例としますと、図の通り、6番目~8番目(下から2番目のコンテンツ)を指定してあげればいい事になります。
よって、数字の6~8を入れています。
一番下のコンテンツは自動で動くようになっていますので、無視して下さって構いません。

タブが2つ以下の場合でもこのままで多分動きますが、4つ以上の場合は、さらに書き加えていかなければなりません。
申し訳ございませんが、コードを参照の上、ご自身でトライしてみて下さい。


1つ注意点があります。
タブ化しているコンテンツのコンテンツ高さをある程度揃える必要があるんです。

僕は、最初4つのコンテンツをタブメニュー化しており、コードもそれに合わせて組みました。
無事動いたのですが、4つ目のコンテンツが縦にバカ長かった為、追従させると、下に突き抜けてコンテンツの一部が見えなくなってしまいました。
改善も出来るかもですが、そこまでする気が無かった為、僕はそのコンテンツを削除しました。
他にも「なんだこれ」という挙動が起こるかもしれませんので、元に戻せるようにだけはしたうえで挑戦してみて下さい。

最後に

最後になりますが、シロマティ (id:shiromatakumi)さんには断りも無く無断でコードを借用し、改造・公開した点をお詫びいたします。
申し訳ございませんでした。