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

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

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

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

JavaScript

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

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

React.js

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

Q&A

0回答

1468閲覧

スクロール量に応じて表示・非表示させるコンテンツの実装方法

takuya_am

総合スコア16

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

JavaScript

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

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

React.js

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

0グッド

0クリップ

投稿2021/03/05 02:35

編集2021/03/05 02:40

ページ構成

  • ヘッダー
  • 左ナビ
  • 右コンテンツ

前提条件

  • 右コンテンツのみスクロール表示するため、右コンテンツのルートコンポーネントをOverlayScrollbarsComponent(npmモジュール)でラップしてスクロール制御している。
  • このコンポーネントが3階層ほど<div>を生成して、実際には孫階層がスクロールを表示している。
// ↓厳密には若干異なりますが階層構造はこのような状態です。 <div id="anything"> <div> <div class="os-viewport"> // ←ここがスクロールバー </div> </div> </div
  • 孫階層に os-viewport というクラスが付与されている。

やりたいこと(知りたいこと)

  • 右コンテンツの深い階層でスクロール量によってフェードイン・アウト表示したいコンテンツを実装したい
  • 実装した処理方法が良いか悪いか知識が足りず判断できないため、より良い方法があれば教えていただきたいです。

→ ref とか使ってうまくできたのかな?とかこれはやっちゃいけない(アンチパターン)だったとか・・・

以下のような構成(かなり簡略化しています)

js

1import React from 'react' 2import { HashRouter, Switch } from 'react-router-dom'; 3import { OverlayScrollbarsComponent } from 'overlayscrollbars-react'; 4 5const Router = () => { 6 const generateRoute = () => { 7 // do something 8 } 9 10 return ( 11 <HashRouter> 12 <Header /> 13 <LeftNav /> 14 <OverlayScrollbarsComponent id="anything"> 15 <Switch>{generateRoute()}</Switch> // generateRouteで生成された奥の方でスクロール量による処理を行う 16 </OverlayScrollbarsComponent> 17 </HashRouter> 18 ) 19} 20 21export default Router;

実際にやった実装

フェードイン・アウトするコンポーネント内にて、
1.OverlayScrollbarsComponentのDOMを id で取得
2.1で取得したDOMから os-viewport というクラス名が付与されているHTMLCollectionを取得
3.(とりあえず1つしかない前提で)os-viewport がついたDOMを取得
4.3で取得したDOMにスクロールイベントリスナーを登録

js

1useEffect(() => { 2 const target = getTargetElement(); 3 if (target) { 4 target.addEventLitener("scroll", event(target)) 5 } 6 return (() => { 7 if (target) { 8 target.removeEventLitener("scroll", event(target)) 9 } 10 }); 11}); 12 13const getTargetElement = () => { 14 targetParent = document.getElementById("anything"); 15 if (targetParent) { 16 const targetElements = targetParent.getElementsByClassName("os-viewport"); 17 if (targetElements.length > 0) { 18 return targetElements[0]; 19 } 20 } 21 return null; 22} 23 24const event = (target) => () => { 25 const pos = target.scrollTop; 26 if (pos > 100) { 27 setIsOpen(true); // ←フェードイン・アウトさせるフラグとして使用 28 } else { 29 setIsOpen(false); 30 } 31}

結果

ブラウザにて正常に動作はしましたが「う~ん、これでいいのか?」みたいな状態です。

より良い方法などがございましたらご教示頂けますと幸いです。
宜しくお願いいたします。

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

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

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

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

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

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

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

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

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問