ど素人から毛を生やす。<延>

スクロールについてくる要素にはやっぱりposition:fixedを使いたい

Web > javascript 2014年12月25日(最終更新:5年前)

2014年12月25日に作成されたページです。
情報が古かったり、僕が今以上のど素人だった頃の記事だったりする可能性があります。

どもです。
今年もあと少し。今日はキーボードを洗おうと思います。

キーボード引っこ抜きには、ダイヤテックのKeyPullerが良さげ。
といっても、これしか持ってないんですけどね(゚∀゚)

 

さて、サイトコンテンツの横にバナーがついてるサイトとか、
一番上へ戻るボタンが常時でているサイトとか、
スクロールによらず、一定の要素を同じ場所に表示し続けるjsというのは結構需要がある感じがします。

単純に設置するだけなら、


if($(window).scrollTop()>200px){
$('.goTop').css({"position":"fixed","top":'0px',"right":"100px"})
}else{
$('.goTop').css({"position":"fixed","top":'0px',"right":"-100px"})
}

あとは要素にtransitionでも設置してアニメーションをつけつつ、要素を画面の外中行き来させれば良い。

でも、これって結構美しくないんですよね。
ウィンドウ幅に関係なく一定の場所に登場するので、狭ければコンテンツに被って見づらいし、広ければ画面の端っこの方に要素が表示されることになります。

h261225

それに、ヘッダーやフッターに要素を被せたくない場合もあります。
そうなると、理想はこういう形になるかと。

h261225_2

これを実現するときに問題になるのは、fixedの基準位置はウィンドウであるということ。
当たり前といえば当たり前なのですが、コンテンツから右20pxの位置、という設定がfixedではできないんですよね。

ならば、absoluteやmarginで位置を調整しよう


y = $(window).scrollTop();;
$('.goTop').css({"position":"absolute","top":y+'px',"right":"-100px"})

なんて思いましたが、これは一見良さ気で実は良くない。
というのも、マウスのホイールで操作したときに動作がガタガタになってしまうんですねこれ。
position:fixedならこのガタガタ現象が起きないので、やはりfixedで行きたい。

※条件が$(window).scroll(function () {});ならこれでもおk(にょんにょんとついてくるやつ)。

 

fixedとabsoluteの仕様は極めて似ている

両者の違いは、absoluteはドキュメントを、fixedはウィンドウを基準にしているということくらいでしょうか。

ので、使い慣れているabsoluteの考え方を使います。

abdoluteでは、topを設定してもrightを設定しなければ、左右の位置は「本来要素のあるべきところ」になります。
これはfixedにも適用できる考え方です。

つまり、positionなしで位置を調整すれば良い

h261225_3
親要素を設置し、中の要素を右寄せに。
z-index:-1;にしてメインコンテンツに干渉しないようにします。

実際にfixedするのはこの親要素の方。
rightもleftも設定されていないので、fixedでtopかbottomを設定すれば上下にだけ固定されます。

追記

z-index:-1にすると、クリックできないっぽいです。
ので、「fixedするのは子要素の方」のが正しいやり方でした。

但し、今のところIEではブラウザ基準になってしまうようです。

最後に、実際に設置してみるとしましょう。

設置するにあたって、気にしなければいけないのは「止める位置」です。
要素の上が一定の位置にきたときに止めるのか、要素の下が一定の位置にきたときに止めるのかで内容が変わります。


// 上端を基準にするとき
$(document).ready(function(){
var goTop = $('動かしたい要素');
var scrollHeight = $(document).height();
var top_y = $(document).height() - $(window).scrollTop();
$(window).bind("scroll", function() {
	scrollHeight = $(document).height();
	scrollPosition = $(window).height() + $(window).scrollTop();
	top_y = $(document).height() - $(window).scrollTop();
		if($(window).scrollTop() > 動き出す位置){
			if ( top_y <= 終端の位置) { 
				goTop.css({"position":"absolute","top":"auto","bottom":"終端のときの位置px"}) 
			} else { 
				goTop.css({"position":"fixed","top":'固定位置px',"bottom":"auto"}) 
			} 
		}else{ 
			goTop.css({"position":"absolute","top":"auto","bottom":"上にいるときの位置"}) 
		} 
	}); 
}); 
// 下端を基準にするとき 
$(document).ready(function(){ 
	var goTop = $('動かしたい要素'); 
	var scrollHeight = $(document).height(); 
	var scrollPosition = $(window).height() + $(window).scrollTop(); 
	var bottom_y = scrollHeight - scrollPosition; 
	$(window).bind("scroll", function() {
		 scrollHeight = $(document).height(); 
		 scrollPosition = $(window).height() + $(window).scrollTop(); 
		 bottom_y = scrollHeight - scrollPosition; 
		 if($(window).scrollTop() > 動き出す位置){
			if ( bottom_y <= 終端の位置) {
			goTop.css({"position":"absolute","top":"終端のときの位置px","bottom":"auto"})
			} else {
			goTop.css({"position":"fixed","top":"auto","bottom":"固定位置px"})
			}

		}else{
			goTop.css({"position":"absolute","top":"上にいるときの位置px","bottom":"auto"})
		}
	});
});

それぞれ、top_y、bottom_yの算出式が違う以外はほぼ同じです。

上端のときは素直に「ドキュメントの高さ」-「縦スクロールした高さ」です。
下端のときは「ドキュメントの高さ」-「縦スクロールした高さ+ウィンドウの高さ」になります。

上や下に固定されているとき、topやbottomを設定する必要のないときはautoにします。
取り敢えず、topとbottomが両方auto以外になっていると誤作動の原因になるので、そこにだけ注意すれば良いでしょう。

この記事は役に立ちましたか?
  • _(:3」∠)_ 面白かった (1)
  • (・∀・) 参考になった (3)
  • (`・ω・´) 役に立った (6)