この記事では、二次リンク効果を実現するためのReact+tsの具体的なコードを参考までに共有します。具体的な内容は次のとおりです。 .tsx ファイル 'react' から { Component, createRef} をインポートします。 './index.less' をインポートします インターフェース状態{ トップ: 任意 ボタンリスト: ボタン[] コンテンツリスト: コンテンツ[] ボタンインデックス: 番号 } インターフェースボタン{ id: 文字列 テキスト: 文字列 } インターフェースコンテンツ{ id: 文字列 テキスト: 文字列 高さ: 数値 上: 番号 } インターフェースProps{ } クラスStairsはComponent<Props, State>を拡張します{ 左リスト: ボタン[] 右リスト: コンテンツ[] kaiguan: ブール値 右 = createRef<HTMLDivElement>() 左 = createRef<HTMLDivElement>() 左Tex = createRef<HTMLDivElement>() // oTop: 数値 | 未定義 viewHeight: 数値 | 未定義 offHeight: 数値 | 未定義 左テキスト = createRef<HTMLDivElement>() 上: 数値 | 未定義 oTop: 数値 | 未定義 コンストラクタ(props: Props) { スーパー(小道具) この状態 = { ボタンリスト: [], コンテンツリスト: [], ボタンインデックス: 0, トップ: 0 } this.LeftList = [] this.RightList = [] this.kaiguan = true this.oTop = 0 } コンポーネントマウント() { this.BtnList(20) this.ConList(20) this.setState({ ボタンリスト: this.LeftList、 コンテンツリスト: this.RightList }) } getRandom(m: 数値, n: 数値): 数値 { parseInt(`${Math.random() * (m - n) + n}`) を返します。 } BtnList(n: 数値) { (i = 0; i < n; i++ とします) { this.LeftList.push({ id: `a${i}`, テキスト: `ボタン${i}`, }); } } ConList(n: 数値) { ConTop = 0 とします。 (i = 0; i < n; i++ とします) { RandomHeight = this.getRandom(736, 1400); とします。 this.RightList.push({ id: `b${i}`, テキスト: `タイトル${i}`, 高さ: ランダム高さ、 トップ: ConTop、 }); ConTop += ランダム高さ; } } Fnスクロール() { // コンソール.log(11) if (this.right.current) { this.oTop = this.right.current.scrollTop; if (this.kaiguan) { // コンソール.log(111) カウントを 0 にする (var i = 0; i < this.state.ContentList.length; i++) { this.oTop >= this.state.ContentList[i].top の場合 { カウント = i } this.setState({ ボタンインデックス: カウント }) } // console.log(ボタンインデックス、カウント) } } // eslint 次の行を無効にする this.oTop == this.state.ContentList[this.state.ButtonIndex].top の場合 { this.kaiguan = true; } } Fn(インデックス: 任意、ev: React.MouseEvent<HTMLDivElement>) { this.viewHeight = document.documentElement.clientHeight / 2 target = ev.target を HTMLDivElement として扱います。 this.offHeight = target.offsetTop // console.log(this.offHeight) this.offHeight > this.viewHeight の場合 { if (this.LeftTex.current) { this.LeftTex.current.scrollTo({ 上: this.offHeight - this.viewHeight - target.clientHeight / 2、 動作:「スムーズ」、 }) } // コンソールログ(this.LeftTex.current) } // console.log(this.offHeight - this.viewHeight - target.clientHeight / 2) this.kaiguan = false; // this.offHeight = ev.target.offsetTop // コンソールログ(ev.target) if (this.right.current) { this.right.current.scroll({ 先頭: this.RightList[index].top, 動作:「スムーズ」、 }); } this.setState({ ボタンインデックス: インデックス }) } ボタンインデックス(インデックス: 数値) { (インデックス >= 3)の場合{ if (this.left.current && this.Lefttext.current) { this.left.current.scrollTop = (index - 3) * this.Lefttext.current.offsetHeight; } } (インデックス<3)の場合{ if (this.left.current) { this.left.current.scrollTop = 0; } } this.setState({ ボタンインデックス: インデックス }) } 与える() { footList = this.state.ButtonList とします。 戻る ( <div> <div className="について"> <div className="スクロール"> <div className="box1" ref="box1"></div> <div className="box2" ref="box2"></div> <div className="スクロール-con" ref="スクロール-con"> <div className="left" ref={this.LeftTex}> <div className="left-con"> {footList.map((item, index) => <div onClick={this.Fn.bind(this, index)} ref={this.Lefttext} className={this.state.ButtonIndex === index ? "ac left-txt" : "left-txt"} key={item.id} > {アイテムテキスト} </div> )} </div> </div> <div className="right" ref={this.right} onScroll={this.FnScroll.bind(this)}> <div className="right-con"> <div クラス名="right-txt" ref="right-txt"> {this.state.ContentList.map((item) => <div style={{ height: item.height }} className="right-title" key={item.id}>{item.text} </div> )} </div> </div> </div> </div> </div> </div> </div> ) } } デフォルトの階段をエクスポート .less ファイル .スクロール{ 幅:100vw; 高さ:100vh; overflow-y: スクロール; .box1 { 高さ: 300px; 背景: #000; 幅: 100%; } .box2 { 高さ: 200px; 背景:トマト; 幅: 100%; } .box3 { 位置: -webkit-sticky; 位置: 固定; 上: 0; 高さ: 100px; 背景:淡い紫赤; zインデックス: 999; 幅: 100%; } .スクロールコン{ 幅:100vw; 高さ:100vh; 位置: -webkit-sticky; 位置: 固定; 上: 100px; ディスプレイ: フレックス; 。左、 。右 { 高さ:100vh; overflow-y: スクロール; } 。左 { 幅: 20vw; .left-txt { 幅: 20vw; 高さ: 100px; テキスト配置: 中央; 行の高さ: 100px; 背景: 赤; } .left-txt.ac { 背景:ライトコーラル; zインデックス: 999; } } 。右 { 幅:80vw; .right-title { 幅: 100%; 高さ: 5vh; 背景: 濃い青; 色: アクア; 行の高さ: 5vh; } } } } 最後に、定義したフォルダをルートに追加します 効果図は以下のとおりです 以上がこの記事の全内容です。皆様の勉強のお役に立てれば幸いです。また、123WORDPRESS.COM を応援していただければ幸いです。 以下もご興味があるかもしれません:
|
>>: Nginx Rewrite の使用シナリオと設定方法の分析
目次1. ESXiをインストールする2. ESXiをセットアップする3. ESXiを起動するESXi...
現在、MySQL を学習中です。私は完全な初心者で、Linux についてはあまり知りません。今後の作...
InnoDB インデックスの物理構造すべての InnoDB インデックスは Btree インデックス...
この記事では、Docker コンテナとフロントエンド プロセスの関係と、コンテナを永続的に実行できる...
1. はじめにデータベース内のデータ量が一定レベルに達すると、システムパフォーマンスのボトルネックを...
目次序文1. 新しいVueプロジェクトを作成する2. WebStormの設定1. デバッガポートを設...
Django Web開発の過程で、HTMLを書く際にバックエンドから同じ名前のリスト変数が渡されるが...
この記事は、参考のためにMySQL 8.0.16のインストールグラフィックチュートリアルを記録してい...
CSS は Web ページで非常に重要な役割を果たします。近年の CSS の発展に伴い、疑似要素/疑...
目次JSON は次の 2 つの構造に基づいて構築されます。 2. JSON形式1. オブジェクト2....
この記事では、モバイル署名機能を実装するためのJavaScriptの具体的なコードを参考までに共有し...
効果画像:実装コードは以下のとおりですビュー <canvas id="radar-c...
1. Tomcatをインストールする1. Docker HubでTomcatイメージを見つける d...
この記事は主に、nginx に基づいてブラウザネゴシエーションキャッシュを設定する詳細なプロセスを紹...
1. 問題開発中に、他のデータベースから MySQL データベース テーブルにデータを挿入すると、次...