はじめに こんにちは、READY TO FASHIONの開発チームの片桐です。現在はブランドの一覧ページを実装しています。 弊社のサービスでは、ユーザーがブランド一覧をより快適に閲覧できるように、イニシャル(頭文字)をクリックすると、そのイニシャルに対応するブランドリストの部分までスムーズにスクロールする機能を実装しました。
今回は、その実装方法とポイントについてご紹介します。
実装の背景 ブランド一覧ページでは、多数のブランドがアルファベット順に表示されており、ユーザーが目的のブランドを探しやすくするために、イニシャルごとのナビゲーションを提供しています。
従来は、イニシャルをクリックするとページが即座にジャンプしていましたが、ユーザー体験を向上させるために、スムーズスクロールを導入することにしました。
実装方法 1. イニシャルボタンの作成 まず、イニシャル(A-Zおよび「その他」)のボタンを生成します。
renderInitialButtons ( ) { const initials = [ ... Object . keys ( this . state . groupedIds ) ] . sort ( ) return ( < div className = 'brands-list__initials' > { initials . map ( initial => ( < button key = { initial } className = { ` brands-list__initial-button ${ this . state . selectedInitial === initial ? 'active' : '' } ` } onClick = { ( ) => this . handleInitialClick ( initial ) } > { initial } < / button > ) ) } < / div > ) }
2. スクロール先の要素にIDを付与 ブランドリストをイニシャルごとにグループ化し、それぞれのグループに対応するIDを設定します。
renderBrandGroups ( ) { return ( < div className = 'brands-list__groups' > { Object . keys ( this . state . groupedIds ) . sort ( ) . map ( initial => ( < div key = { initial } className = 'brands-list__group' id = { ` group- ${ initial } ` } > < h2 className = 'brands-list__group-title' > { initial } < span > { this . state . groupedIds [ initial ] . length } 件 < / span > < / h2 > < / div > ) ) } < / div > ) }
3. スムーズスクロールの実装 イニシャルボタンがクリックされたときに、対応するセクションまでスムーズにスクロールします。
handleInitialClick ( initial ) { this . setState ( { selectedInitial : initial } ) const element = document . getElementById ( ` group- ${ initial } ` ) if ( element ) { element . scrollIntoView ( { behavior : 'smooth' , block : 'start' } ) } }
scrollIntoView
メソッドの behavior
オプションに 'smooth'
を指定することで、スムーズスクロールを実現しています。
4. モーダルからのイニシャル選択(モバイル対応) モバイルデバイスでは、画面幅の関係でイニシャルボタンを横に並べることが難しいため、モーダルを使用してイニシャルを選択できるようにしています。
handleSelectInitial ( initial ) { this . setState ( { selectedInitial : initial , isModalOpen : false } ) const element = document . getElementById ( ` group- ${ initial } ` ) if ( element ) { element . scrollIntoView ( { behavior : 'smooth' , block : 'start' } ) } }
5. 全体のコード 上記のポイントを踏まえた全体のコードは以下のようになります。
class BrandsList extends React . Component { constructor ( props ) { super ( props ) ; this . state = { selectedInitial : null , groupedIds : { } , isModalOpen : false } } componentDidMount ( ) { this . fetchGroupedBrandIds ( ) ; } fetchGroupedBrandIds ( ) { fetch ( '/api/v1/brands/grouped_brand_ids_by_initial' , { method : 'GET' , headers : { 'Content-Type' : 'application/json' } , credentials : 'same-origin' } ) . then ( response => response . json ( ) ) . then ( data => { this . setState ( { groupedIds : data . grouped_ids } ) ; } ) ; } handleInitialClick ( initial ) { this . setState ( { selectedInitial : initial } ) ; const element = document . getElementById ( ` group- ${ initial } ` ) ; if ( element ) { element . scrollIntoView ( { behavior : 'smooth' , block : 'start' } ) ; } } handleSelectInitial ( initial ) { this . setState ( { selectedInitial : initial , isModalOpen : false } ) ; const element = document . getElementById ( ` group- ${ initial } ` ) ; if ( element ) { element . scrollIntoView ( { behavior : 'smooth' , block : 'start' } ) ; } } handleModalOpen ( ) { this . setState ( { isModalOpen : true } ) ; } handleModalClose ( ) { this . setState ( { isModalOpen : false } ) ; } renderInitialButtons ( ) { } renderBrandGroups ( ) { } render ( ) { return ( < div className = 'brands-list' > { this . renderInitialButtons ( ) } { this . renderBrandGroups ( ) } < BrandModal isOpen = { this . state . isModalOpen } onClose = { ( ) => this . handleModalClose ( ) } onSelectInitial = { ( initial ) => this . handleSelectInitial ( initial ) } / > < / div > ) } }
scrollIntoView
メソッド :特定のDOM要素が見える位置までスクロールします。 behavior: 'smooth'
を指定することで、スムーズなアニメーションになります。 アクセシビリティの向上 :スムーズスクロールにより、ユーザーは現在のページ内で移動していることが視覚的に理解しやすくなります。 モバイル対応 :モバイルデバイスではモーダルを使用してイニシャルを選択できるようにし、同じロジックでスムーズスクロールを実現しています。 注意点 ブラウザの互換性 : scrollIntoView
の behavior
オプションは一部の古いブラウザではサポートされていない可能性があります。必要に応じてポリフィルを検討してください。 まとめ 今回は、Reactでイニシャルをクリックした際に対応するセクションまでスムーズにスクロールする機能の実装方法をご紹介しました。 scrollIntoView
メソッドを活用することで、シンプルなコードでユーザー体験を向上させることができます。
ユーザーがブランド一覧を快適に閲覧できるよう、今後も機能の改善を続けていきます。
READY TO FASHIONでは一緒に働くエンジニアを募集しています! ファッションに興味があるエンジニアのご応募お待ちしております!
READY TO FASHIONでは一緒に働く仲間を募集しています