続き / スクロールに合わせて、移動するメニュー(要素)

  • このエントリーをはてなブックマークに追加
  • LINEで送る

この投稿には最新版(続き)があります。
懲りず ) jQueryを使った画面スクロールに合わせてついてくるフローティングメニューが一応形になりまんた。

jQuery練習中

二転三転中、最初の見極めが甘いんだろうなぁ
作って試してみると、じゃあこうゆう時はどうなる?こうなったら?が出てくること出てくること。
あーしたい、こーしたいって欲も。

前回の練習以降に変更した事。

_1.footerと被った部分の処理とあえて移動させない処理。
ウインドウサイズをちょこちょこ縮めていくと(普通はそんな使い方しないけど)メニューとフッターが被る。
処理を1.ヘッダーが画面内にある場合 / 2.フッターが画面内にある場合 / 3.両方画面内にない場合の3段階に分けて、メニューが移動する位置などを決めるようにした。

_2.コンテンツの中身が全然ないhtmlの場合
4.ヘッダーもフッターも同じ画面にある場合はどうなるの?と思って試してみた。
コンテンツ部分を短くしたら(このページは現在製作中です的な長さ、公開するなよって話)不具合が。

_3.コンテンツの中身が全然ないhtmlの場合:修正
短い場合の修正として、コンテンツの高さを無理やり広げた。
そうしたところ、今度はbodyの高さを取得する順番なんかが狂ってしまった。
スクロールに合わせて移動するメニューなのに移動させない処理を追加

_4.javascript外部化、要素名を変数化
いままでのままだと、移動する要素ややヘッダーやフッターの名前を変更したい時に書き換える部分が沢山あるので変数にした、速度とかも。あとhead内の記述から.jsにした。

外部化したけど、どんなhtmlにも読み込んだらそのまま使えるの?

これがまた使えないんですよねぇ。
まずフッター要素が無いと使えない。ふむー

次に、position周りの指定は自分でやる必要がある。
移動する要素のidも揃える、これは仕方がない。

他の人はどうやってるんだろう?

こういったフローティングメニューを配布してる人の設置方法を流し読みした感じだと、
いろんなhtmlに使う場合でも、フロートさせる要素しか変更しないで平気そうなんですよね。

どうやったら簡単に使いまわせるようになるんだろうか(次の課題)。

[追記 / 20100518 19:24]
ちょっと調べた。
positionを使った2カラムレイアウトの考え方がそもそも違ってたみたい。
レイアウト
大体#navにabsoluteをつけるか / relativeかの2パターンあった。

うちのやり方は

#navにabsolute

(親要素にrelative)。
で#articleのmarginに#navのwidth分を設定してズラす。
これだと見た目は2カラムになっているけど、実際は1カラム。

メリット
左右marginや#navのwidthなんかをemで設定出来る、あと#articleのwidthを設定しなくてもいい。

デメリット
見た目が2カラムだけど実際は1カラムだから、#articleの内容が#navより少ないと#footerが食い込んでくる(#navの高さで#containerが拡張されない)。

#containerがrelativeで#navもrelativeの場合

floatと併用してやってるみたい。

メリットデメリット
両方ともfloatの2カラムと同じ。

#navも#articleもwidthをちゃんと設定しなきゃいけないし、
左右marginにemを使ったりしたら文字サイズを拡大したときにカラムが崩れる。
アバウトに組めないけど普通はpxできっちりやってるからあまり困らない?

なにより#articleの内容が#navより少なくても、
#containerにclearfixを使えばrelativeのデメリットに書いた現象は起きないです。

うちが今回使ってたcssの組み方だと、最初の理由で#articleの高さが無い時に#footerが食いこむ。
それを回避する為にjQueryを使って(練習なので)#navの高さを#articleの高さに移植した。

なので、高さを計算するのに#articleか#footerの名前が必要だった。
#containerにmin-height使えばいいんだけど、せっかくだから高さ計算しないでも使いたいなぁ。

#navにもrelativeの方すると、#articleが短いときに重なりはしないだろうけど、ウインドウを縮めていったときにどうやってstopする位置を計算するんだろう?

現状のソースと使い方

直接floatingmenu.jsを、開いたりするのはこっちから。

使い方

_1. / 以下の二つを保存して読み込む

_jsフォルダに保存してるならこんな感じ。
[html]
<script type="text/javascript" src="_js/jquery-1.4.2.js"></script>
<script type="text/javascript" src="_js/floatingmenu.js"></script>
[/html]

_2. / “floatingmenu.js”を開いて11行目から適当に変更

  • offsetY = 13; //フロートさせるボックスの上マージン 単位はpx。
  • duration = 800; //処理時間 (ミリ秒) 0だとposition:fixedのようになる、チラつくけど
  • _mcName = ‘#main’; //メインコンテンツ部分
  • _foName = ‘#primaryNavigation’; //フロートさせるボックス部分
  • _ftName = ‘#footer’; //フッター部分

_3. / htmlとpositionの処理

現状footer要素が必要
フロートさせるボックスにposition:absolute; 親要素にposition:relative;

ソース / javascriptソースをフォーマットしてくれるサイトを利用しました。
Online javascript beautifier

[修正した / 20100518 17:23]
でもまだ修正がある、どうしよう。
[js]//jquery.easing.1.3.jsから
jQuery.extend(jQuery.easing, {
easeOutCubic: function (x, t, b, c, d) {
return c * ((t = t / d – 1) * t * t + 1) + b;
}
});

$(function () {
//[設定する部分]————————-
offsetY = 13; //メニュー上のマージン 1em
duration = 800; //処理時間 (ミリ秒) 0だとposition:fixedのようになる、チラつくけど
_mcName = ‘#main’; //メインコンテンツ部分
_foName = ‘#primaryNavigation’; //フロートさせるボックス部分
_ftName = ‘#footer’; //フッター部分
//[/設定する部分]————————-
mainContent = $(_mcName).outerHeight(true); //メインコンテンツの高さ
navHeight = $(_foName).outerHeight(true); //ナビゲーションのmargin+border+padding+heightを合わせた高さ
navHeights = navHeight + offsetY;

bodyHeight = $(‘body’).outerHeight(true); //コンテンツの高さ
naviSetY = $(_foName).offset().top; //ナビゲーションの初期座標(=margin・paddingを含めたheadの高さ)
footerSetY = parseInt($(_ftName).offset().top); //フッターの初期座標(=margin・paddingを含めたheadの高さ)
naviMarginSetY = naviSetY – offsetY; //ヘッダの高さを超えた時の位置用
//↓body全体の高さからfooterの座標を引くとbodyのpaddingやmarginなどを含めたfooterの高さになる?
footerArea = bodyHeight – footerSetY; //footer、実際の高さ
desiredHeight = navHeights + footerArea; //必要な高さ(footer+naviの高さ)
naviMaxY = bodyHeight – desiredHeight; //naviが重ならずに降りられる一番下
floatObjMoveChk(mainContent – navHeights);
});

//スクロール毎の処理

function floatObjMove() {
$(window).scroll(function () {
var naviScrollTop = parseInt($(this).scrollTop()); //スクロール量
if (navHeights < windowHeight) {

//スクロール量が最初の位置より小さい内は
if (naviScrollTop <= naviSetY) {
$(_foName).animate({
top: 0
}, {
duration: duration,
queue: false,
easing: "easeOutCubic"
});
}
//
else if (naviMaxY < naviScrollTop) {
$(_foName).animate({
top: naviMaxY – naviSetY
}, {
duration: duration,
queue: false,
easing: "easeOutCubic"
});
}
//(naviMaxY-naviSetYの理由:メニュー自体ヘッダーの下で0だけど、bodyからみたらヘッダ分下にある
//ヘッダもフッタも無い位置
else {
$(_foName).animate({
top: naviScrollTop – naviMarginSetY
}, {
duration: duration,
queue: false,
easing: "easeOutCubic"
});
}
//ウインドウサイズが足りないので動かない。
} else {
//console.log("ウィンドウの高さ:"+windowHeight," / メニューの高さ:"+desiredHeight,"クリック出来ないメニューが出来るので動かさない");
}
});
}

//リサイズしたらwindowのサイズを変更
$(window).resize(function () {
windowHeight = parseInt($(window).height()); //windowのサイズ
});

function floatObjMoveChk(val) {
if (val < 0) {
$(_mcName).css(‘height’, navHeight);
} else {
windowHeight = $(window).height(); //変更後windowのサイズ
floatObjMove();
}
}[/js]

修正前
[js]//jquery.easing.1.3.jsから
jQuery.extend(jQuery.easing, {
easeOutCubic: function (x, t, b, c, d) {
return c * ((t = t / d – 1) * t * t + 1) + b;
}
});

$(function () {
//[設定する部分]————————-

offsetY = 13; //メニュー上のマージン 1em
duration = 800; //処理時間 0だとposition:fixedのようになる、チラつくけど
_mcName = ‘#main’; //メインコンテンツ部分
_foName = ‘#primaryNavigation’; //フロートさせるボックス部分
_ftName = ‘#footer’; //フッター部分

//[/設定する部分]————————-

mainContent = $(_mcName).outerHeight(true); //メインコンテンツの高さ
navHeight = $(_foName).outerHeight(true); //ナビゲーションのmargin+border+padding+heightを合わせた高さ
navHeights = navHeight + offsetY;

floatObjMoveChk(mainContent – navHeights);
});

function floatObjMoveSet() {
bodyHeight = $(‘body’).outerHeight(true); //コンテンツの高さ
windowHeight = $(window).height(); //windowのサイズ
naviSetY = $(_foName).offset().top; //ナビゲーションの初期座標(=margin・paddingを含めたheadの高さ)
footerSetY = parseInt($(_ftName).offset().top); //フッターの初期座標(=margin・paddingを含めたheadの高さ)
naviMarginSetY = naviSetY – offsetY; //ヘッダの高さを超えた時の位置用
//↓body全体の高さからfooterの座標を引くとbodyのpaddingやmarginなどを含めたfooterの高さになる?
footerArea = bodyHeight – footerSetY; //footer、実際の高さ
desiredHeight = navHeights + footerArea; //必要な高さ(footer+naviの高さ)
naviMaxY = bodyHeight – desiredHeight; //naviが重ならずに降りられる一番下
/*footerHeight=$(_ftName).outerHeight(true);*/
floatObjMove();

}

//スクロール毎の処理

function floatObjMove() {
$(window).scroll(function () {
var naviScrollTop = parseInt($(this).scrollTop()); //スクロール量
if (navHeights < windowHeight) {

//スクロール量が最初の位置より小さい内は
if (naviScrollTop < naviSetY) {
$(_foName).animate({
top: naviScrollTop
}, {
duration: duration,
queue: false,
easing: "easeOutCubic"
});
}
//
else if (naviMaxY < naviScrollTop) {
$(_foName).animate({
top: naviMaxY – naviSetY
}, {
duration: duration,
queue: false,
easing: "easeOutCubic"
});
}
//(naviMaxY-naviSetYの理由:メニュー自体ヘッダーの下で0だけど、bodyからみたらヘッダ分下にある
//ヘッダもフッタも無い位置
else {
$(_foName).animate({
top: naviScrollTop – naviMarginSetY
}, {
duration: duration,
queue: false,
easing: "easeOutCubic"
});
}
//ウインドウサイズが足りないので動かない。
} else {
//console.log("ウィンドウの高さ:"+windowHeight," / メニューの高さ:"+desiredHeight,"クリック出来ないメニューが出来るので動かさない");
}
});
}

//リサイズしたらwindowのサイズを変更
$(window).resize(function () {
windowHeight = parseInt($(window).height()); //windowのサイズ
//console.log("リサイズしたよ:"+windowHeight);
floatObjMoveSet();
});

function floatObjMoveChk(val) {
if (val < 0) {
$(_mcName).css(‘height’, navHeight);
} else {
floatObjMoveSet();
}
}[/js]

  • このエントリーをはてなブックマークに追加
  • LINEで送る

SNSでもご購読できます。

コメントを残す


You can add images to your comment by clicking here.