質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

3回答

5230閲覧

サイドメニューが下まで行ったらそこで固定するJS

KSS

総合スコア17

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

3クリップ

投稿2015/06/17 02:54

編集2015/06/17 02:55

下記リンクを参考にスクロールを作成したのですが
メイン部分がJSにより長さが変わることがある(例:クリック押下でheightが伸びる等)ため、うまく動作しません。

理想としては、サイドバーは常に上に固定され、かつメイン部分のボトムまできたら下に固定されることなのですが、、、、
メインの長さが動的に変化する場合、どのように対処したらよいでしょうか。

> リンク

lang

1$(window).load(function () { 2 3 //該当のセレクタなどを代入 4 5 var mainArea = $("#main"); //メインコンテンツ 6 var sideWrap = $("#sideWrap"); //サイドバーの外枠 7 var sideArea = $("#side"); //サイドバー 8 9 /*設定ここまで*/ 10 11 var wd = $(window); //ウィンドウ自体 12 13 14 //メインとサイドの高さを比べる 15 16 var mainH = mainArea.height(); 17 var sideH = sideWrap.height(); 18 19 20 if(sideH < mainH) { //メインの方が高ければ色々処理する 21 22 //サイドバーの外枠をメインと同じ高さにしてrelaltiveに(#sideをポジションで上や下に固定するため) 23 sideWrap.css({"height": mainH,"position": "relative"}); 24 25 //サイドバーがウィンドウよりいくらはみ出してるか 26 var sideOver = wd.height()-sideArea.height(); 27 28 //固定を開始する位置 = サイドバーの座標+はみ出す距離 29 var starPoint = sideArea.offset().top + (-sideOver); 30 31 //固定を解除する位置 = メインコンテンツの終点 32 var breakPoint = sideArea.offset().top + mainH; 33 34 wd.scroll(function() { //スクロール中の処理 35 36 if(wd.height() < sideArea.height()){ //サイドメニューが画面より大きい場合 37 if(starPoint < wd.scrollTop() && wd.scrollTop() + wd.height() < breakPoint){ //固定範囲内 38 sideArea.css({"position": "fixed", "bottom": "20px"}); 39 40 }else if(wd.scrollTop() + wd.height() >= breakPoint){ //固定解除位置を超えた時 41 sideArea.css({"position": "absolute", "bottom": "0"}); 42 43 } else { //その他、上に戻った時 44 sideArea.css("position", "static"); 45 46 } 47 48 }else{ //サイドメニューが画面より小さい場合 49 50 var sideBtm = wd.scrollTop() + sideArea.height(); //サイドメニューの終点 51 52 if(mainArea.offset().top < wd.scrollTop() && sideBtm < breakPoint){ //固定範囲内 53 sideArea.css({"position": "fixed", "top": "20px"}); 54 55 }else if(sideBtm >= breakPoint){ //固定解除位置を超えた時 56 57 //サイドバー固定場所(bottom指定すると不具合が出るのでtopからの固定位置を算出する) 58 var fixedSide = mainH - sideH; 59 60 sideArea.css({"position": "absolute", "top": fixedSide}); 61 62 } else { 63 sideArea.css("position", "static"); 64 } 65 } 66 67 68 }); 69 70 } 71 72});

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

要素のリサイズイベントを取得出来るjQueryプラグインがある様です。
次のリンクなどが参考になると思います。

要素のリサイズイベントを取得 - Qiita

要素の中身が変更されたことを知る - Qiita

Ben Alman » jQuery resize event
※上記のQiitaで紹介されているものとは別のプラグインですが、参考になるのではないでしょうか

あとは最初のリンクで紹介されているプラグインexResizeを利用して次の様にすると、変化した高さの分も考慮された動作が得られるのではないでしょうか。

lang

1// #mainがリサイズされた時 2$("#main").exResize(function() { 3 // メインの高さを取得し直す 4 mainH = mainArea.height(); 5}

追記
リサイズイベントではなくスクロールイベント内で処理しても良いかもしれません。

lang

1wd.scroll(function() { 2 // #mainの高さがmainHよりも高くなった時 3 if ( mainArea.height() > mainH ) { 4 // メインの高さを取得し直す 5 mainH = mainArea.height(); 6 } 7}

投稿2015/06/17 13:59

編集2015/06/17 14:22
flat

総合スコア617

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

KSS

2015/06/18 01:15

事情によりプラグインを追加することができない条件となっており、なんとか今のままでの対応を考えております。 また、追記にありました対応も実験済みですがスクロールがヘッダーに合わせようとすることで動きがカクカクしてしまいました。
guest

0

こんな感じでしょうか?
スクロール時の処理の中に高の取得や判別の部分を入れました。

lang

1<!DOCTYPE html> 2<html> 3<head> 4<script src="https://code.jquery.com/jquery-1.9.1.min.js"></script> 5 <meta charset="utf-8"> 6 <title></title> 7 <style> 8 body{text-align:center; margin:0; padding:0;} 9 .demoLink{margin:15px 0;} 10 p{font-weight:bold;font-size:20px; color:#fff; padding:10px; line-height:1.5; margin:0;} 11 #header{width:1000px; margin:0 auto 30px;background:#666; padding:30px 0;} 12 #contents{width:1000px; margin:0 auto 30px; overflow:hidden;} 13 #main{width:720px; float:left;background:#aaa;} 14 #sideWrap{width:260px; float:right;position:relative;border-bottom:2px solid red;} 15 #side{width:260px; background:#eee;} 16 #side p{color:#333;font-size:15px; border:1px solid #ccc;} 17 #footer{background:#444;padding:20px 0; height:600px;} 18 #nobiru{background:#000; height:30px; color:#fff; text-align:center; transition:height 0.5s;} 19 #nobiru.nobita{height:500px;} 20 </style> 21 <script> 22 $(window).load(function () { 23 24 //該当のセレクタなどを代入 25 26 var mainArea = $("#main"); //メインコンテンツ 27 var sideWrap = $("#sideWrap"); //サイドバーの外枠 28 var sideArea = $("#side"); //サイドバー 29 30 /*設定ここまで*/ 31 32 var wd = $(window); //ウィンドウ自体 33 34 var sideOffsetTop = sideArea.offset().top; //サイドバーの座標 35 36 37 function setSidePosition(){ 38 39 //メインとサイドの高さを比べる 40 var mainH = mainArea.height(); 41 var sideH = sideArea.height(); 42 43 if(sideH < mainH) { //メインの方が高ければ色々処理する 44 45 //サイドバーの外枠をメインと同じ高さにしてrelaltiveに(#sideをポジションで上や下に固定するため) 46 sideWrap.css({"height": mainH,"position": "relative"}); 47 48 //サイドバーがウィンドウよりいくらはみ出してるか 49 var sideOver = wd.height()-sideArea.height(); 50 51 //固定を開始する位置 = サイドバーの座標+はみ出す距離 52 var starPoint = sideOffsetTop + (-sideOver); 53 54 //固定を解除する位置 = メインコンテンツの終点 55 var breakPoint = sideOffsetTop + mainH; 56 }else{ 57 //メインの方が高くなければsideWrapの高さをリセット 58 sideWrap.css({"height": "auto","position": "static"}); 59 } 60 61 if(wd.height() < sideArea.height()){ //サイドメニューが画面より大きい場合 62 if(starPoint < wd.scrollTop() && wd.scrollTop() + wd.height() < breakPoint){ //固定範囲内 63 sideArea.css({"position": "fixed", "bottom": "20px"}); 64 65 }else if(wd.scrollTop() + wd.height() >= breakPoint){ //固定解除位置を超えた時 66 sideArea.css({"position": "absolute", "bottom": "0"}); 67 68 } else { //その他、上に戻った時 69 sideArea.css("position", "static"); 70 71 } 72 73 }else{ //サイドメニューが画面より小さい場合 74 75 var sideBtm = wd.scrollTop() + sideArea.height(); //サイドメニューの終点 76 77 if(mainArea.offset().top < wd.scrollTop() && sideBtm < breakPoint){ //固定範囲内 78 sideArea.css({"position": "fixed", "top": "20px"}); 79 80 }else if(sideBtm >= breakPoint){ //固定解除位置を超えた時 81 82 //サイドバー固定場所(bottom指定すると不具合が出るのでtopからの固定位置を算出する) 83 var fixedSide = mainH - sideH; 84 85 sideArea.css({"position": "absolute", "top": fixedSide}); 86 87 } else { 88 sideArea.css("position", "static"); 89 } 90 } 91 92 } 93 94 wd.on("scroll",function(e){ 95 setSidePosition(); //スクロールで実行 96 }); 97 setSidePosition(); //最初にも1回実行 98 99 }); 100 101 102 $(function(){ 103 //mainAreaが伸びたり縮んだりするボタン 104 $("#nobiru").click(function(){ 105 $(this).toggleClass("nobita"); 106 }); 107 }); 108 </script> 109</head> 110<body> 111<div id="header"> 112 <p>私はヘッダー。</p> 113</div><!-- / #header --> 114 115<div id="contents"> 116 117 <div id="main"> 118 <p style="height:700px">それがしがメインエリア。</p> 119 <div id="nobiru">ココ押すと伸びたり縮んだり</div> 120 </div><!-- / #main --> 121 122 <div id="sideWrap"> 123 <div id="side"> 124 <p style="height:500px">我はサイドバー。</p> 125 </div><!-- / #side --> 126 </div><!-- / #sideWrap --> 127 128</div><!-- / #contents --> 129 130<div id="footer"> 131 <p>ワタスはフッター。</p> 132</div><!-- / #footer --> 133</body> 134</html>

投稿2015/06/18 19:26

ina

総合スコア127

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

KSS

2015/06/19 10:31

親切にすべて記載していただき、ありがとうございます。 しかし。。。残念ながらスクロールの終わりがヘッダー部分を超えると削除されてしまいました。 もしかしたら今の構成自体がよくないのかもしれません。。。
ina

2015/06/19 10:41

すみません。「スクロールの終わりがヘッダー部分を超える」がどういう状況かよく分からないので、もう少し説明をもらえるとありがたいです。
guest

0

メイン部分がJSにより長さが変わることがある(例:クリック押下でheightが伸びる等)

上記のタイミングで下記の位置や高さ、画面ロードにのみしているスクロール時の処理を最定義してやれば適切に動くと思います。

投稿2015/06/17 12:15

chiku_

総合スコア1464

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

KSS

2015/06/17 23:15

いかんせんクリック処理が多いため、スクロール時に処理しようとしています
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問