![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?5a7ff87)
2カラムレイアウトで良くあるページをスクロールしていくと
「サイドナビの"途中"で固定され、フッター直前で固定解除」されるのを
jQueryで実現したいんです。
「サイドナビの途中で固定(でもフッターに重なる)」と
「最初から固定されてるけどフッター手前で固定解除」という
2種類のjQueryを見つけたので、その2つを合体して
上記の希望する動作にしたいんです。
以下2つのコードです。
■サイドナビの途中(class="kotei")で固定
$(function(){
var nav = $('.kotei'),
offset = nav.offset();
$(window).scroll(function(){
if($(window).scrollTop() > offset.top) {
nav.addClass('fix-on');}
else {nav.removeClass('fix-on');}});
});
※スタイルシート
.fix-on { position : fixed; top : 0; z-index : 10000; }
■フッター(id="footer")手前で固定解除
window.onload=function(){
var onoff =
$("#fotter").offset().top - $(window).height() + 0; //フッターまでの高さを計算=onoff
$(window).scroll(function(){
if($(window).scrollTop() < onoff) //onoffの高さがスクロール量より大きい場合
$(".kotei").addClass("fix-on"); //class="kotei"にfix-onを付与する
else
$(".kotei").removeClass("fix-on"); //それ以外はfix-onを解除
});
}
■自力で合体したけどうまく動作しなかったコード
$(document).ready(function(){
var nav = $(".kotei"),
offset = nav.offset(),
onoff =
$("#footer").offset().top - $(window).height() + 0;
$(window).scroll(function(){
if($(window).scrollTop() > offset.top) {
nav.addClass("fix-on");}
else if($(window).scrollTop() > onoff) {
nav.removeClass("fix-on");}
else {nav.removeClass("fix-on");}});
});
オフセットを2重に設定したのが競合しているのでしょうか。。?
※※※補足※※※現在のホームページレイアウト(html)
<body>
<#wrap>
<#content>
略
</#content>
</#wrap>
<#header>
略
</#header>
<#side-nav>
<li>略</li>
</#side-nav>
<#footer>
</body>
普通の2カラムと違うところは<#header>をposition:absoluteでトップに絶対配置している事、
<#content>と<#side-nav>は<#header>分のマージンを上部に取っている事、
<#wrap>は<#content>のみを囲っている事です。
■ヘッダー■←:absoluteでトップに
□□■■■■
□□■コン■
ナビ■テン■←maegin-top+コンテンツだけにwrap
□□■ツ■■
□□■■■■
■フッター■
2つの条件を両方満たしたjQueryを見つけたんですが、
<wrap>で<side-menu>と<content>の両方を包んでいないと
既存のjQueryでは動作しないようです。
それで2つのjQuertを合体したいという経緯に至りました。
No.2ベストアンサー
- 回答日時:
A No1です。
お礼を読みましたが、やりたいことがよくわかりません。
ご質問文の図解とhtmlの構成を参考に作成してみたのですが・・・
>position:absoluteで絶対位置指定しておかないと機能しないのですね。
最初にご提示のようなposition:fixでの方法もあるかと思いますが、結局、この指定と違う動作をさせる時に、position:absoluteなどにしているので、単純化しているだけです。
>コードの意味を調べたり、~~
数行のコードなので、大して難しくはないと思いますが、念のため説明しておきますと、
移動したい部分(今回の場合は#side-navと解釈)の縦の位置指定をすれば良いだけですので、移動可能な範囲(縦位置の最小値、最大値)を求めておいて、その中で位置を指定しているだけです。計算上範囲からはみ出した場合は、最大値(又は最小値)にセットしているだけです。
よくわかりませんが、こういうこと?
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="ja">
<head><title>test</title>
<meta http-equiv="Content-Style-Type" content="text/css">
<meta http-equiv="Content-Script-Type" content="text/javascript">
<style type="text/css">
html, body{ margin:0; padding:0; }
.header{ height:100px; background-color:#aff; }
.content{ height:1000px; background-color: #ddd; }
.footer{ clear:both; height:50px; background-color:#ffa; }
#side-bar{
width:150px;
float:left;
background-color: #ffa;
}
#side-nav{
position:absolute;
width:150px; left:0;
background-color:#faf;
list-style-type:none;
margin:0; padding:0;
}
</style>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7. …
<script type="text/javascript">
$(function(){
var nav = $("#side-nav"); //移動する部分の要素を取得
//位置調整関数
var adjust = function(){
var sTop = $(window).scrollTop(); //全体のスクロール量
var sMin = $("#side-bar").offset().top + $("#side-bar").height(); //縦位置の最小値
var sMax = $(".footer").offset().top - nav.height(); //縦位置の最大値
nav.css("top", Math.min(Math.max(sTop, sMin), sMax)); //要素の縦位置を設定
}
//スクロール時、リサイズ時のイベント設定
$(window).scroll(function(){ adjust(); })
.resize(function(){ adjust(); });
//初期設定での位置調整表示
adjust();
});
</script>
</head>
<body>
<div class="header">
header略
</div>
<div id="side-bar">
<ul>
<li>スクロールされるメニュー1</li>
<li>スクロールされるメニュー2</li>
<li>スクロールされるメニュー3</li>
</ul>
</div>
<ul id="side-nav">
<li>navi1 略</li>
<li>navi2 略</li>
<li>navi3 略</li>
</ul>
<div class="content">
content略
</div>
<div class="footer">
footer
</div>
</body>
</html>
2度もご回答ありがとうございます。
今回ご提示下さったコードで正常に動作させる事が出来ました。
配布されているjQueryをそのまま使っているような人間ですので
数行の簡単なコードでも//補足コメントはありがたいです。
ネットで探し回ったコードよりもシンプルな記述ですし、
希望していた動作通りに機能するので非常に感謝しております。
ご親切にありがとうございました。
No.1
- 回答日時:
回答がないみたいなので…
headerとfooterにかからない範囲で、side-navを上下に移動させたいということと解釈しました。
headerをabsoluteにする必然性がないのと、どうせスクリプトに頼ることになるのですから、side-navだけをabsoluteにしておいて、スクリプトで上下に移動するという方式にしています。
最初に計算をしておいても良いのですが、ブラウザのサイズをリサイズすると計算値が変わる可能性があるので、都度計算するようにしています。
*HTML4.01になっていますので、HTML5にする場合は適宜修正を。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="ja">
<head><title>test</title>
<meta http-equiv="Content-Style-Type" content="text/css">
<meta http-equiv="Content-Script-Type" content="text/javascript">
<style type="text/css">
html, body{ margin:0; padding:0; }
.header{ height:100px; background-color:#aff; }
.content{ height:1000px; margin-left:100px; }
.footer{ height:50px; background-color:#ffa; }
#side-nav{
position:absolute;
width:100px;
top:100px; left:0;
background-color:#faf;
list-style-type:none;
margin:0; padding:0;
}
</style>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7. …
<script type="text/javascript">
$(function(){
var nav = $("#side-nav");
var adjust = function(){
var sTop = $(window).scrollTop();
var sMin = $(".header").height()
var sMax = $(".footer").offset().top - nav.height();
nav.css("top", Math.min(Math.max(sTop, sMin), sMax));
}
$(window).scroll(function(){ adjust(); })
.resize(function(){ adjust(); });
});
</script>
</head>
<body>
<div class="header">
header略
</div>
<ul id="side-nav">
<li>navi1 略</li>
<li>navi2 略</li>
<li>navi3 略</li>
</ul>
<div class="content">
content略
</div>
<div class="footer">
footer
</div>
</body>
</html>
回答ありがとうございます。
ご返事遅くなってしまいスミマセン。
ご提案下さったコードを元に
コードの意味を調べたり、
色々いじくって自分なりに検証しておりました。
position:absoluteで
絶対位置指定しておかないと機能しないのですね。
サイドナビの途中から固定したいもので、
<div id="side-bar">
<ul>
<li>スクロールされるメニュー1</li>
<li>スクロールされるメニュー2</li>
<li>スクロールされるメニュー3</li>
</ul>
<ul id="side-nav">
<li>navi1 略</li>
<li>navi2 略</li>
<li>navi3 略</li>
</ul>
</div>
こんな風にDIVで囲ってみると、
スクロールされるメニューと重なってしまって
<div id="side-bar">
<ul>
<li>スクロールされるメニュー1</li>
<li>スクロールされるメニュー2</li>
<li>スクロールされるメニュー3</li>
</ul>
<div id="relative">
<ul id="side-nav">
<li>navi1 略</li>
<li>navi2 略</li>
<li>navi3 略</li>
</ul>
</div>
</div>
と<ul id="side-nav">の親要素として
さらにDIVを追加し、position:relative;を指定すると
今度はside-nav自体が表示されなくなったりでお手上げ状態なんです。。
どうも相談内容が悪かったのか、なかなか回答も頂けないので
半ば諦めモードなんですが
締め切らずにもう少しだけ待ってみようと思います。
ご回答ありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- HTML・CSS 書籍を見つつサイト造りの練習をしているのですが、見た目が一致しません 2 2022/11/28 15:00
- JavaScript スマフォではボタンを表示させたくない 2 2023/01/20 14:26
- JavaScript jQueryでのドラッグアンドドロップについて 1 2022/07/30 09:10
- JavaScript jQueryでのレスポンシブが綺麗に動かない 3 2022/06/21 11:08
- HTML・CSS テキストを画面の真ん中に配置したいです。 2 2022/11/25 16:11
- オープンソース cssで中央寄せ 1 2023/05/19 06:25
- JavaScript jQueryでのドラッグアンドドロップについて 1 2022/07/07 21:04
- HTML・CSS ヘッダーの画像にメインエリアがかぶってしまいます 1 2022/11/28 14:06
- PHP style.cssのjQuery条件付きcssが機能しない 4 2022/07/17 18:27
- HTML・CSS cssの display: flex;で横並びにならずに困ってます 1 2022/12/04 13:18
関連するカテゴリからQ&Aを探す
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
jqueryのsortableで一部ソート...
-
「jQuery」アコーディオンメニ...
-
どの<li><a> が押されたか判別...
-
開閉式ツリー型メニューについて
-
.innerHTMLの不一致?
-
PukiWikiの左メニューでonMouse...
-
jQuery タブメニューへのダイ...
-
jQueryについて質問なのですが...
-
カテゴリページ内 複数タブ
-
別フレームからの背景の変更
-
javascriptでEnterキーをtabキ...
-
滑らかに開閉するメニューを作...
-
jQueryスライドメニューの初歩...
-
jquery ドロップダウンメニュー...
-
MAX関数を使ってからLEFT JOIN...
-
createElementで作成した要素を...
-
iframe内のリンクが飛ばないの...
-
Lightbox2でのキャプションにつ...
-
画像ファイルの合成
-
クリックで背景変更するタグ
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
jqueryのsortableで一部ソート...
-
クリックした<a>タグのみにClas...
-
どの<li><a> が押されたか判別...
-
【javascript で動的に a タグ...
-
文字と数字が混在する要素のsor...
-
javascriptでEnterキーをtabキ...
-
チェックボックスに入っている...
-
複数のラジオボタン項目でのテ...
-
jquery ドロップダウンメニュー...
-
jQueryのeqで最後からn番目以降...
-
JavaScriptで、?マークとコロ...
-
質問に答えていくと、回答によ...
-
Jqueryでリストのスクロール
-
多階層ドロップダウンのスマホ...
-
JQueryタブのアクティブ アン...
-
gridstack.jsについて教えてく...
-
タブ切り替えの初期表示について
-
オンマウスで画像ロールオーバ...
-
「jQuery」アコーディオンメニ...
-
複数の画像をランダム(シャッ...
おすすめ情報