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;到此這篇關(guān)于React實現(xiàn)菜單欄滾動的文章就介紹到這了,更多相關(guān)React 菜單欄滾動內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
React配置多個代理實現(xiàn)數(shù)據(jù)請求返回問題
這篇文章主要介紹了React之配置多個代理實現(xiàn)數(shù)據(jù)請求返回問題,本文通過示例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-08-08
react 項目 中使用 Dllplugin 打包優(yōu)化技巧
在用 Webpack 打包的時候,對于一些不經(jīng)常更新的第三方庫,比如 react,lodash,vue 我們希望能和自己的代碼分離開,這篇文章主要介紹了react 項目 中 使用 Dllplugin 打包優(yōu)化,需要的朋友可以參考下2023-01-01
react源碼層深入刨析babel解析jsx實現(xiàn)
同作為MVVM框架,React相比于Vue來講,上手更需要JavaScript功底深厚一些,本系列將閱讀React相關(guān)源碼,從jsx -> VDom -> RDOM等一些列的過程,將會在本系列中一一講解2022-10-10

