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

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

新規登録して質問してみよう
ただいま回答率
85.31%
React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

Q&A

解決済

1回答

1649閲覧

Reactで作ったモーダルメニューを表示させるとメイン画面のスクロール位置がトップに戻ってしまう。

tmyk1979

総合スコア145

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

0グッド

0クリップ

投稿2022/07/07 17:08

前提

ReactでWebページを作っており、メニューボタンをクリックorタップするとモーダルでメニューが表示されるようにしたのですが、モーダルを表示すると必ずスクロールが一番上まで戻ってしまいます。

実現したいこと

モーダルでメニューを表示させてもメイン画面のスクロール位置が保持されるようにしたいです。

該当のソースコード

React

1import React from 'react' 2 3//activeがtrueになるとモーダルが表示されるようにしています。 4function Modal({active}) { 5 6 const scrollTop = () => { 7 return Math.max(window.pageYOffset, document.documentElement.scrollTop, document.body.scrollTop); 8 }; 9 10 if(active) { 11 const position = scrollTop(); 12 console.log(position); //ここにしかコンソールログは書いていないのに、コンソールを見るとスクロール位置が出力された後に0pxという出力も出ており、メイン画面の必ずスクロール位置が必ずトップまで戻ってしまいます。 13 14 document.body.style.overflowY = "hidden"; 15 document.body.style.height = "100vh"; 16 17 document.documentElement.style.overflowY = "scroll"; 18 19 document.body.style.position = "fixed"; 20 document.body.style.top = -position; 21 22 } else { 23 24 document.body.style.overflowY = "auto"; 25 document.body.style.height = "auto"; 26 27 document.documentElement.style.overflowY = "auto"; 28 document.body.style.position = "static"; 29 30 } 31 32 return ( 33 <> 34 <ul className="navlist toggle_contents" style={{ 35 transition: '1.5s', 36 opacity: active ? 1 : 0, 37 zIndex: active ? 4 : -1, 38 }}> 39 <li className="navitem current_page_item"><a href="#">About</a></li> 40 <li className="navitem"><a href="#">Feature</a></li> 41 <li className="navitem"><a href="#">Blog</a></li> 42 <li className="navitem"><a href="#">Contact</a></li> 43 </ul> 44 </> 45 ) 46} 47 48export default Modal

試したこと

Googleで「React モーダル スクロール位置」などと検索して、
https://qiita.com/IgnorantCoder/items/3b66c9e96c2f24e0d09e
や、
https://qiita.com/ragnar1904/items/184a10fbb4d216625aa8
の記事など読んだのですが、自分のコードに落とし込む事ができずにいます。

詳しい方がおられましたら教えていただけると幸いです。
宜しくお願いします。

補足情報(FW/ツールのバージョンなど)

VSCode1.61.8

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

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

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

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

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

hoshi-takanori

2022/07/08 05:34

React で document.body とか document.documentElement とかいじるのは良くないはず…。
tmyk1979

2022/07/08 14:31 編集

いつもアドバイスありがとうございます。 > React で document.body とか document.documentElement とかいじるのは良くないはず…。 知りませんでした。 もっと基礎から勉強し直して、別の書き方など見つかり次第修正しようと思います。
guest

回答1

0

自己解決

解決した後に作業を進めてしまい、そこから不要なコードを削ったため余計な記述があるかも知れませんが、何とか自己解決しました。

React

1 2import React from 'react' 3import {useEffect, useState } from 'react' 4 5function Modal(props) { 6 7 const [scrollY, setScrollY] = useState(0); 8 const [spb,setSpb] = useState(0); 9 const [bodyHeight, setBodyHeight] = useState(0); 10 11 window.addEventListener('scroll', () => { 12 setSpb(window.scrollY); 13 }); 14 15 useEffect(() => { 16 if (props.active) { 17 const y = window.scrollY; 18 setScrollY(y); 19 document.getElementById('body').style.overflow = "hidden"; 20 document.getElementById('body').style.height = "100vh"; 21 document.getElementById('body').scrollTo(0, spb); 22 window[`scrollTo`]({ top: 0 }) 23 } else { 24 document.getElementById('body').style.position = ""; 25 document.getElementById('body').style.top = ""; 26 document.getElementById('body').style.height = ""; 27 window.scrollTo(0, scrollY); 28 } 29 }, [props.active]); 30 31 return ( 32 <> 33 <ul className="navlist toggle_contents" style={{ 34 transitionDuration: '1.5s', 35 opacity: props.active ? 1 : 0, 36 zIndex: props.active ? 4 : -1, 37 visibility: props.active ? 'visible' : 'hidden', 38 }} 39 tabIndex={'0'}> 40 <li className="navitem current_page_item"><a href="#" tabIndex={'0'}>About</a></li> 41 <li className="navitem"><a href="#" tabIndex={'0'}>Feature</a></li> 42 <li className="navitem"><a href="#" tabIndex={'0'}>Blog</a></li> 43 <li className="navitem"><a href="#" tabIndex={'0'}>Contact</a></li> 44 </ul> 45 <div id="space" style={{ 46 display: props.active ? "block" : "none", 47 }}></div> 48 </> 49 ) 50} 51 52export default Modal

document.bodyとかdocument.documentElementという記述は無くすためにBodyタグの直下にid="body" class="body"のdivを咬ませました。

スクロールの問題は、position:fixedをやめてoverflow:hiddenとheight:100vhとし、トップから必要分だけスクロールさせる事でモーダルを非表示にしてもスクロール位置が維持されるようにしたところ、意図した通りの動きになりました。

アドバイスをくださったhoshi-takanori様と、この質問を気にかけて下さった方にお礼を申し上げます。
ありがとうございました。

投稿2022/07/20 19:29

tmyk1979

総合スコア145

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.31%

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

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

質問する

関連した質問