スクロールしてフッターで止まる、上揃いのサイドバー

Javascript

よく見かけるようになった、スクロールしていくとサイドバーがそのままウインドウについてきて、フッターの箇所まで来ると止まるというのを作ってみました。

いろいろなところを参考に考えながら作ったので、JSに無駄なものが多いかと思いますがひとまず出来たので置いておこうと思います。

ウインドウサイズが小さくてもずれない

こういう動きのサイトで、ウインドウサイズが小さいとそのままコンテンツ部分にかぶってしまうというのをたまに見ます。

原因はだいたい動く要素のfixedの値がそのままなためです。ですのでウインドウサイズが小さくてもかぶらないようにしました。

JavaScriptのソース

IE6にも対応するためif文で処理を分けてます。

$(function(){

	//固定する要素
	var box = $('#nav');
	//上の間隔
	var topMarge = box.offset().top;
	//下の間隔調整用
	var bottomMarge = 0;

	//////////////////////////////////////////
	var boxOffset = box.offset();
	var boxSize = {"width": box.width(), "height": box.height()};
	var footerOffset = $("#footer").offset();
	var stopPosition = footerOffset.top - boxSize.height - boxOffset.top - bottomMarge;
	var uaInfo = navigator.userAgent;

	$(window).bind('scroll resize load' , function() {
		var scrollOffset = $(this).scrollTop() || document.body.scrollTop;
		fixedStart(scrollOffset);
		fixedEnd(scrollOffset);
		fixedNo(scrollOffset);
	});

	//////////////////////////////////////////
	//スクロール時
	function fixedStart(scrollOffset){
		var winSize = $(window).width();
		var contentWidth = $('#wrap').width();
		var leftPos = $(window).scrollLeft()*(-1);

		var leftScroll = (winSize - contentWidth)/2;
		if(winSize < contentWidth){
			leftScroll = leftPos;
		}

		if(scrollOffset + topMarge > boxOffset.top) {
			box.css({
				"position": "fixed",
				"top": 0,
				"left": leftScroll,
				'float': 'none'
			});
			if(uaInfo.match('MSIE 6.0')){
				box.css({
	    	        "position": "relative",
					"top": scrollOffset - boxOffset.top + topMarge,
					'left': 0
		       	});
			}
		}
	};

	//////////////////////////////////////////
	//下までいった時
	function fixedEnd(scrollOffset){
		if((scrollOffset + boxSize.height) > footerOffset.top) {
			box.css({
				"position": "relative",
	            "top": stopPosition,
				"left": 0,
				'float': 'none'
	        });
			if(uaInfo.match('MSIE 6.0')){
			   	box.css({
					"position": "relative",
					'left': 0
				});
			}
	 	}
	};

	//////////////////////////////////////////
	//上に戻った時
	function fixedNo(scrollOffset){
		if((scrollOffset + topMarge == boxOffset.top)){
			if(uaInfo.match('MSIE 6.0')){
				box.css({
					"position": "static",
					'top': 0,
					'left': 0
				});
			}
			else{
				box.css({
					"position": "relative",
	            	"top": 0,
					"left": 0,
					'float': 'none'
	        	});
			}
		}
	};

});

サイドバーが長いとサイドバーの下のものがフッターまで行かないと見えない状態になるので、短い場合に使うといいかなと思います。