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

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

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

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Q&A

解決済

1回答

462閲覧

[jquery] window scrollしたらサイドバーも同時にスクロールしたい

DaisukeMori

総合スコア217

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

0グッド

0クリップ

投稿2022/08/05 04:09

編集2022/08/05 18:17

前提

  • position: stickyで追従型にしています。
  • 記事部分は無限スクロールコンテンツ

実現したいこと

①windowスクロールする
②ページがスクロールされると同時にサイドバーのoverscroll: scroll-yもスクロール

どんな状態であってもスクロールバーはユーザーが操作可能な状態を維持する。

発生している問題・エラーメッセージ

スクロールするとサイドバーはスクロールしてくれるので一見要件は満たしたかのように思いましたが、
その後、上にスクロールしてもサイドバーが上まで戻ってくれない(問題1)。
それどころか、スクロールバーを手動でつかんでもスクロールできない(問題2)。

【考えたロジック】
①windowスクロールされたら作動
②スクロール位置が50より大きくスクロールされたらサイドバーのポジションを100pxにし、scrollTopで2000まで移動する
③スクロール位置が50を下回ったらそれぞれ元に戻す ← animate({scrollTop: 0}がうまくいかない

最小構成にしたところ
少なくともなぜか③がうまくいきましたが、実データではうまくいきません。
また最小構成でも、サイドバーにフォーカスを当ててスクロールしてもうまくサイドバーのみスクロールができないのは実データと同様です。

該当のソースコード

最小構成にしています

html

1<!DOCTYPE html> 2<html lang="en"> 3<head> 4 <meta charset="UTF-8"> 5 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <title>Document</title> 8 <link rel="stylesheet" href="./style.css"> 9</head> 10 <body> 11 <main class="top"> 12 <article> 13 <div id="contents"></div> 14 </article> 15 <aside class="sidebar"> 16 <p style="color: red">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p> 17 <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p> 18 <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p> 19 <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, <span style="color: red">sunt in culpa qui officia deserunt mollit anim id est laborum.</span></p> 20 </aside> 21 </main> 22 23 <script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script> 24 <script src="./main.js"></script> 25 </body> 26</html> 27 28

scss

1body { 2 overflow-x: hidden; 3 color: #474645; 4 background: #FFFCFC; 5 overscroll-behavior: none; 6 main { 7 padding: 0 20px; 8 aside.sidebar { 9 display: none; 10 } 11 } 12 @media screen and (min-width:768px) { 13 main { 14 display: flex; 15 justify-content: space-between; 16 width: 640px; 17 margin: 0 auto; 18 padding: 0; 19 article { 20 width: 100%; 21 } 22 } 23 } 24 @media screen and (min-width:1024px) { 25 main { 26 width: 880px; 27 margin: 0 auto; 28 article { 29 width: 70%; 30 } 31 aside.sidebar { 32 display: block; 33 width: 24%; 34 padding: 0 0 300px 0; 35 position: sticky; 36 top: 0; 37 height: 100vh; 38 transition: 0.5s; 39 overflow-y: scroll; 40 -ms-overflow-style: none; 41 scrollbar-width: none; 42 &::-webkit-scrollbar { 43 display:none; 44 } 45 } 46 } 47 } 48 @media screen and (min-width:1120px) { 49 main { 50 width: 1024px; 51 article { 52 width: 680px; 53 } 54 aside.sidebar { 55 width: 240px; 56 } 57 } 58 } 59}

js

1// 簡易無限スクロールコンテンツ 2(() => { 3 window.fetch = url => new Promise(resolve => { 4 setTimeout(() => { 5 const content = '<div>コンテンツが入ります</div>'; 6 resolve({ text: async () => content }); 7 }, 100) 8 }); 9})(); 10(() => { 11 const contents = document.getElementById('contents'); 12 13 const infiniteScrollObserver = new IntersectionObserver(entries => { 14 entries.forEach(entry => { 15 if (!entry.isIntersecting) { 16 return; 17 } 18 infiniteScrollObserver.unobserve(entry.target); 19 loadContent(); 20 }); 21 }); 22 23 let i = 0; 24 const max = 2147483647; 25 26 const loadContent = async () => { 27 const response = await fetch('https://example.com/load?i=' + i); 28 29 contents.insertAdjacentHTML('beforeend', 30 '<div>' + 31 '<div>#' + (i + 1) + '</div>' + 32 await response.text() + 33 '</div>' 34 ); 35 i++; 36 if ( i < max ) infiniteScrollObserver.observe(contents.lastElementChild); 37 }; 38 loadContent(); 39})(); // ここまで簡易無限スクロールコンテンツ 40 41 42$(function(){ 43 $(window).on('scroll', function () { 44 if($(window).scrollTop() > 50) { 45 $('.sidebar').css('top', '100px').animate({scrollTop: 2000}, 100); 46 } else { 47 $('.sidebar').css('top', '0').animate({scrollTop: 0}, 100); 48 } 49 }); 50});

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

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

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

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

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

hatena19

2022/08/05 04:31

html, cssのコードも提示してください。 回答するには他者が、状況を再現できるだけのコードが必要です。
DaisukeMori

2022/08/05 05:41

最小単位でコード動かせるようにしました。 ただ気になるのは最小単位で動かしてみるとなぜか【考えたロジック】の③部分がうまくいきます(実データではうまくいかない)。 最小構成ファイルでも、サイドバーにフォーカスを当ててスクロールしてもうまくサイドバーのみスクロールができないのは実データと同様です。 ちなみにビジネスでのデータのため実データをお見せすることはできません。
DaisukeMori

2022/08/05 05:49

すみません。再度サイドバーのコンテンツ量増やしてみました。 こちらのコードなら、③部分もおかしな動きになるはずです。 あくまで憶測ですがサイドバーのコンテンツ量が多いと変な挙動になってそうですね。 ただこれだと運用面で支障をきたすのため、何かしらの改修が必要です。
guest

回答1

0

ベストアンサー

scrollイベントはスクロール中繰り返し発生します。
そこで、animate() も繰り返し実行されてキューにたまっておかしくなるのだと思います。
stop() で実行中のアニメーションを停止させればうまくいきそうです。

js

1$(function(){ 2 $(window).on('scroll', function () { 3 if($(window).scrollTop() > 50) { 4 $('.sidebar').css('top', '100px').stop().animate({scrollTop: 2000}, 100); 5 } else { 6 $('.sidebar').css('top', '0').stop().animate({scrollTop: 0}, 100); 7 } 8 }); 9});

.stop() | jQuery API Documentation

投稿2022/08/05 08:18

hatena19

総合スコア33620

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

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

DaisukeMori

2022/08/05 09:17

ありがとうございました。 試したら、要件は満たせそうです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問