React實現(xiàn)菜單欄滾動功能
更新時間:2024年03月25日 11:02:47 作者:卡卡舅舅
本文將會基于react實現(xiàn)滾動菜單欄功能,點擊菜單,內(nèi)容區(qū)域會自動滾動到對應卡片,內(nèi)容區(qū)域滑動,指定菜單欄會被選中,代碼簡單易懂,感興趣的朋友一起看看吧
簡介
本文將會基于react實現(xiàn)滾動菜單欄功能。
技術(shù)實現(xiàn)
實現(xiàn)效果
點擊菜單,內(nèi)容區(qū)域會自動滾動到對應卡片。內(nèi)容區(qū)域滑動,指定菜單欄會被選中。
ScrollMenu.js
import {useRef, useState} from "react"; import './ScrollMenu.css'; export const ScrollMenu = ({products}) => { // 獲取 categoryProductMap const categoryProductMap = new Map(); products.forEach(product => { const category = product.category; let categoryProductList = categoryProductMap.get(category); if (!categoryProductList) { categoryProductList = []; } categoryProductList.push(product); categoryProductMap.set(category, categoryProductList); }); // 獲取類別列表 const categoryList = Array.from(categoryProductMap.keys()); // 菜單選中索引 const [current, setCurrent] = useState(0); /** * 內(nèi)容引用 */ const contentRef = useRef(); /** * 當左側(cè)菜單點擊時候 */ const onMenuClick = (idx) => { if (idx !== current) { // 內(nèi)容自動滾動到對應菜單位置 contentRef.current.scrollTop = height.slice(0, idx).reduce((a, b) => a + b, 0); setCurrent(idx); } } /** * 計算右側(cè)商品類別卡片高度 */ const height = []; const itemHeight = 25; categoryList.forEach((category, index) => { var productCnt = categoryProductMap.get(category).length; height.push((productCnt + 1) * itemHeight); // 0.8 是header高度 }); console.log(height) /** * 當右側(cè)內(nèi)容滾動時候 */ const onContentScroll = () => { const scrollTop = contentRef.current.scrollTop; if (current < height.length - 1){ const nextIdx = current + 1; // 計算下一個位置高度 const nextHeight = height.slice(0, nextIdx).reduce((a, b) => a + b, 0); console.log('scrollTop', scrollTop, 'nextHeight', nextHeight, 'nextIdx', nextIdx) if (scrollTop >= nextHeight) { contentRef.current.scrollTop = nextHeight; setCurrent(nextIdx); return; } } if (current > 0) { const lastIdx = current - 1; // 計算上一個位置高度 const lastHeight = height.slice(0, lastIdx).reduce((a, b) => a + b, 0); console.log('scrollTop', scrollTop, 'lastHeight', lastHeight, 'lastIdx', lastIdx) if (scrollTop <= lastHeight) { contentRef.current.scrollTop = lastHeight; setCurrent(lastIdx); return; } } } return ( <div className='scroll-menu'> <div className='menu'> { // 菜單列表 categoryList.map((category, index) => { return ( <div className={"menu-item" + ((index === current )? '-active' : '')} key={`${index}`} id={`menu-item-${index}`} onClick={(event) => { onMenuClick(index) }}> {category} </div> ) }) } </div> <div className='content' ref={contentRef} onScroll={(event) => { onContentScroll() }}> { categoryList.map((category, index) => { // 獲取類別商品 const productList = categoryProductMap.get(category); return ( <div key={index}> <div className='content-item-header' key={`${index}`} id={`content-item-${index}`} style={{ height: itemHeight }} >{category}</div> { productList.map((product,idx) => { return <div className='content-item-product'style={{ height: itemHeight }} key={`${index}-${idx}`} >{product.name}</div> }) } </div> ) }) } </div> </div> ) }
ScrollMenu.css
.scroll-menu { display: flex; flex-direction: row; width: 300px; height: 100px; } .menu{ width: 90px; height: 100px; display: flex; flex-direction: column; } .menu-item { text-align: center; vertical-align: middle; } .menu-item-active { text-align: center; vertical-align: middle; background-color: lightcoral; } .content { width: 210px; overflow: auto; } .content-item-header{ text-align: left; vertical-align: top; background-color: lightblue; } .content-item-product{ text-align: center; vertical-align: center; background-color: lightyellow; }
App.js
import './App.css'; import {ScrollMenu} from "./component/scroll-menu/ScrollMenu"; const App = ()=> { const products = [ { category:'蔬菜', name:'辣椒' }, { category:'蔬菜', name:'毛豆' }, { category:'蔬菜', name:'芹菜' }, { category:'蔬菜', name:'青菜' }, { category:'水果', name:'蘋果' }, { category:'水果', name:'梨' }, { category:'水果', name:'橘子' }, { category:'食物', name:'肉' }, { category:'食物', name:'罐頭' } , { category:'食物', name:'雞腿' } ]; return ( <ScrollMenu products={products}/> ) } export default App;
到此這篇關于React實現(xiàn)菜單欄滾動的文章就介紹到這了,更多相關React 菜單欄滾動內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
React配置多個代理實現(xiàn)數(shù)據(jù)請求返回問題
這篇文章主要介紹了React之配置多個代理實現(xiàn)數(shù)據(jù)請求返回問題,本文通過示例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-08-08react 項目 中使用 Dllplugin 打包優(yōu)化技巧
在用 Webpack 打包的時候,對于一些不經(jīng)常更新的第三方庫,比如 react,lodash,vue 我們希望能和自己的代碼分離開,這篇文章主要介紹了react 項目 中 使用 Dllplugin 打包優(yōu)化,需要的朋友可以參考下2023-01-01react源碼層深入刨析babel解析jsx實現(xiàn)
同作為MVVM框架,React相比于Vue來講,上手更需要JavaScript功底深厚一些,本系列將閱讀React相關源碼,從jsx -> VDom -> RDOM等一些列的過程,將會在本系列中一一講解2022-10-10