前提
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});
回答1件
あなたの回答
tips
プレビュー