赞
踩
本文将会基于react实现滚动菜单栏功能。
点击菜单,内容区域会自动滚动到对应卡片。内容区域滑动,指定菜单栏会被选中。
- 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);
-
- /**
- * 内容引用
- */
- const contentRef = useRef();
-
- /**
- * 当左侧菜单点击时候
- */
- const onMenuClick = (idx) => {
- if (idx !== current) {
- // 内容自动滚动到对应菜单位置
- contentRef.current.scrollTop = height.slice(0, idx).reduce((a, b) => a + b, 0);
- setCurrent(idx);
- }
- }
-
- /**
- * 计算右侧商品类别卡片高度
- */
- 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)
- /**
- * 当右侧内容滚动时候
- */
- 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>
-
-
- )
- }

- .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;
- }

- 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;

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。