要素を一定範囲のみでスクロールさせるjs

サイドバーなどを追従させる時ヘッダーやフッターにかぶってしまうのを制御したかったのでやってみました。

完成デモ

まず基本的なhtmlとcss

<div id="header">
	header
</div>
<div id="main">
	main
</div>
<div id="footer">
	footer
</div>
<a href="" class="fixed">要素</a>
#header {
	height: 600px;
	width: 1%;
	background: #ffb2b2;
	display: table-cell;
	text-align: center;
	vertical-align: middle;
	font-size: 24px;
	font-weight: bold;
}
#footer {
	height: 600px;
	width: 1%;
	background: #9ed7ff;
	display: table-cell;
	text-align: center;
	vertical-align: middle;
	font-size: 24px;
	font-weight: bold;
}
#main {
	background: #eee;
	height: 2000px;
	font-size: 24px;
	font-weight: bold;
	width: 100%;
}
.fixed {
	width: 100px;
	height: 500px;
	background: #fff;
	position: fixed;
	top: 100px;
	left: 0px;
	border-radius: 0 6px 6px 0;
	border: 2px solid #333;
}

 

まず最初にいろんな要素の高さとってヘッダーとフッターにかぶらないように(main部分のみ追従)できるようにしてみました。

	$(window).on('load scroll resize', function(){
		var top = $('#header').height() + 30;
		var bottom =  $('#footer').offset().top - 30;
		var content = $('.fixed').height() + 30;
		var scroll = $(window).scrollTop();
		if((scroll + content) > bottom){
			$('.fixed').css({
				'position': 'absolute',
				'top': bottom - content + 30
			});
		} else if(top < scroll){
			$('.fixed').css({
				'position': 'fixed',
				'top': '30px'
			});
		} else {
			$('.fixed').css({
				'position':'absolute',
				'top': top + 30
			});
		}
	});

になります。

デモ01

でもこれだと画面サイズがmin-widthよりも大きい時は問題ないんですが、画面サイズを小さくした時に途中からfixedになるんでスクロールすると飛び出てきてまたいなくなる。みたいな変なうごきになっちゃいます。
なのでちょっと修正…

	$(window).on('load scroll resize', function(){
		var top = $('#header').height() + 30;
		var bottom =  $('#footer').offset().top - 30;
		var content = $('.fixed').height() + 30;
		var scroll = $(window).scrollTop();
		if((scroll + content) > bottom){
			$('.fixed').css({
				'position': 'absolute',
				'top': bottom - content + 30
			});
		} else if(top < scroll){
			$('.fixed').css({
				'position': 'absolute',
				'top': scroll + 30
			});
		} else {
			$('.fixed').css({
				'position':'absolute',
				'top': top + 30
			});
		}
	});

デモ02

fixed部分をabsoluteにして横に固定!
んで毎回スクロールごとに高さとって動かす。みたいにしたんですが…
どうやらこれだとPCだとガタガタとしててスムーズにスクロールされないらしい!
SPだけだったらこれで問題ないみたいなんですがね…
なのでまたまたちょっと修正

	$(window).on('load scroll resize', function(){
		var top = $('#header').height() + 30;
		var bottom =  $('#footer').offset().top - 30;
		var content = $('.fixed').height() + 30;
		var scroll = $(window).scrollTop();
		var x = $(window).width();
		var min_x = 1000;
		if((scroll + content) > bottom){
			$('.fixed').css({
				'position': 'absolute',
				'top': bottom - content + 30
			});
		} else if(top < scroll){
			if(min_x > x){
				$('.fixed').css({
					'position': 'absolute',
					'top': scroll + 30
				});
			} else {
				$('.fixed').css({
					'position': 'fixed',
					'top': '30px'
				});
			}
		} else {
			$('.fixed').css({
				'position':'absolute',
				'top': top + 30
			});
		}
	});

横幅とmin-widthの幅も取得してそれmin-widthよりも小さくなったらabsoluteで固定してスクロール!min-widthよりも大きかったらfixedで動かす!
みたいな分岐もつけくわえて一応完成です。
もっといいやり方ありそうですが…とりあえずここまで。

完成デモ

そんな感じで終わりです。

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です