カテゴリ:   CSS/Jquery
タグ:

ちょっと前からこれ半分導入してたんだけど、うまいこと動かなかったり気持ち悪かったりしてて、
ようやくまぁ許せる範囲で挙動してくれたので、備忘録ついでに。


↓こういうやつ
jquery


元々のコード

<script>
$(function(){
var contentHeight = $("html, body").height();
var windowHeight = $(window).height();
var target = $(".fix_box");
var targetHeight = target.outerHeight();
var targetPosition = target.position();
var footer = $("#footer");
var footerHeight = footer.outerHeight();
$(window).resize(function(){
windowHeight = $(this).height();
});
$(window).scroll(function(){
var scrollTop = $(this).scrollTop();
var visibleBottom = scrollTop + windowHeight;
var targetBottom = targetPosition.top + targetHeight;
if(visibleBottom >= targetBottom) {
if(footerHeight > contentHeight - visibleBottom) {
target.css({position:"fixed", bottom: footerHeight - (contentHeight - visibleBottom)});
} else {
target.css({position:"fixed", bottom: 0});
}
} else {
target.css({position:"static", bottom: "auto"});
}
});
});
</script>




こんな感じにいじくりました


 <script>
$(window).load(function () {
var contentHeight = $("html, body").height();
var windowHeight = $(window).height();
var target = $("#sidebar");
var targetHeight = target.outerHeight();
var targetPosition = target.position();
var main = $("#main");
var mainHeight = main.outerHeight();
var mainPosition = main.position();
var footer = $("#footer-wrap");
var footerHeight = footer.outerHeight();
$(window).resize(function(){
windowHeight = $(this).height();
});
$(window).scroll(function(){
var scrollTop = $(this).scrollTop();
var visibleBottom = scrollTop + windowHeight;
var targetBottom = targetPosition.top + targetHeight;
var mainBottom = mainPosition.top + mainHeight;
if(mainBottom >= targetBottom ) {
if(visibleBottom >= targetBottom) {
if(footerHeight > contentHeight - visibleBottom ) {
target.css({position:"fixed", bottom: footerHeight - (contentHeight - visibleBottom ) + 20 });
$('#sidebar-inner').width('89.7%');
document.getElementById('sidebar-inner').style.width = '89.7%';
} else {
target.css({position:"fixed", bottom: 20});
$('#sidebar-inner').width('89.7%');
document.getElementById('sidebar-inner').style.width = '89.7%';
}
} else {
target.css({position:"static", bottom: "auto"});
$('#sidebar-inner').width('100%');
document.getElementById('sidebar-inner').style.width = '100%';
}
} else {
target.css({position:"static", bottom: "auto"});
$('#sidebar-inner').width('100%');
document.getElementById('sidebar-inner').style.width = '100%';
}
});
});
</script>

・ブログ本文がサイドバーより短い場合にうまく動かなかったので、赤い部分でブログ本文がサイドバーより短い場合は固定せんでええでっていうif文を追記
・iframeやらバンバン使ってたので、青い部分で最初にloadを追加

■ざっと解説

 <script>
$(window).load(function () { //ロードが終わったら計算開始
var contentHeight = $("html, body").height(); //全体の高さ
var windowHeight = $(window).height(); //画面の高さ
var target = $("#sidebar"); //固定させたい部分
var targetHeight = target.outerHeight(); //固定させたい部分の高さ
var targetPosition = target.position(); //固定させたい部分の表示位置
var main = $("#main"); //ブログ本文(メッセージボードとか込み)の指定
var mainHeight = main.outerHeight(); //ブログ本文の高さ
var mainPosition = main.position(); //ブログ本文の高さ
var footer = $("#footer-wrap"); //フッターの指定
var footerHeight = footer.outerHeight(); //フッターの高さ
$(window).resize(function(){ //ブラウザの大きさ変えた時に常に高さを再取得
windowHeight = $(this).height();
});
$(window).scroll(function(){ //スクロールさせたら計算開始
var scrollTop = $(this).scrollTop(); //画面に表示されている上端の位置取得
var visibleBottom = scrollTop + windowHeight; //画面に表示されている下端の位置取得
var targetBottom = targetPosition.top + targetHeight; //固定させたい部分(サイドバー)の下端を取得
var mainBottom = mainPosition.top + mainHeight; //ブログ本文の下端を取得
if(mainBottom >= targetBottom ) { //ブログ本文がサイドバーより長いか
  if(visibleBottom >= targetBottom) {
if(footerHeight > contentHeight - visibleBottom ) {  //(分岐1)
target.css({position:"fixed", bottom: footerHeight - (contentHeight - visibleBottom ) + 20 });
$('#sidebar-inner').width('89.7%');
document.getElementById('sidebar-inner').style.width = '89.7%';
} else { //(分岐2)
target.css({position:"fixed", bottom: 20});
$('#sidebar-inner').width('89.7%');
document.getElementById('sidebar-inner').style.width = '89.7%';
}
} else { //(分岐3)
target.css({position:"static", bottom: "auto"});
$('#sidebar-inner').width('100%');
document.getElementById('sidebar-inner').style.width = '100%';
}
} else { //(分岐4)
target.css({position:"static", bottom: "auto"});
$('#sidebar-inner').width('100%');
document.getElementById('sidebar-inner').style.width = '100%';
}
});
});
</script> 

分岐1
・ブログ本文がサイドバーより長い
・画面に表示されている下端がサイドバーよりも下に来ている
・フッターが既に表示されている
 ⇒サイドバーを固定させて「画面下から表示されているフッター+20px」の位置を指定
 ⇒これによってフッターに併せて上にズレる

分岐2
・ブログ本文がサイドバーより長い
・画面に表示されている下端がサイドバーよりも下に来ている
・フッターが表示されていない
 ⇒サイドバーを画面下から20pxの位置に固定

分岐3
・ブログ本文がサイドバーより長い
・画面に表示されている下端がサイドバーよりも下に来ていない
 ⇒つまりまだ固定させる必要がないのでposition:staticで下からの位置を自動に指定

分岐4
・ブログ本文がサイドバーより短い
 ⇒固定させる必要がないのでposition:staticで下からの位置を自動に指定

多分こんな感じ。

多分青い部分を書き換えればコピペでいけんちゃう?
たぶん…

■注意した点
・結構外部のRSSだのiframeだの使ってるので、最初の計算開始にloadを指定

・元々のコードだと「サイドバーの高さ」が「ブログ本文」よりも長い場合に気持ち悪い挙動をしていたので、赤字の部分みたく、ブログ本文の高さを取得して、ブログ本文>サイドバーの高さのときに計算開始するようなif文をつけないとダメっぽい。場所があそこでいいかは知らんが。

・tableタグの高さを指定してないと取得できないっぽいので、table使ってる場合はheight=""で指定しておく

・元々のレイアウト方法に問題?僕のブログの場合はサイドバーとブログ本文のカラムをdisplay:inline-blockで並べてるんだけど、それだとサイドバーをposition:fixedにした場合にメインカラムに被っちゃうので、メインカラムの方にfloat:rightをつけて無理やり解決。position:absolute;で並べた方が綺麗なんだろうだけどだるい。別にこれで動くしいいかな~と(良くない)

・サイドバーにposition:fixedを付けることによってなぜかサイドバーの親要素の幅?が変わる関係で、レイアウトが変わっちゃったので、fixedがつく場合とつかない場合はwidthを個別に設定。全て最初のレイアウトのせい。きもちわるい。


■残りの課題
ブログ本文内にtwitterをAPIで埋め込んだ場合、iframeの高さが取得できないようでものすごく気持ち悪いことに。
今後これは挑戦したいな~。

 

Comment & Trackbacks

コメント
コメントフォーム
評価する
  • 1
  • 2
  • 3
  • 4
  • 5
  • リセット
  • 1
  • 2
  • 3
  • 4
  • 5
  • リセット

関連記事

新着一覧