.net网站开发技术简介,wordpress接口,免费咨询法律顾问,wordpress 社交插件简介 本文将会基于react实现滚动菜单栏功能。
技术实现
实现效果 点击菜单#xff0c;内容区域会自动滚动到对应卡片。内容区域滑动#xff0c;指定菜单栏会被选中。 ScrollMenu.js
import {useRef, useState} from react;
import ./ScrollMenu.css;export co…简介 本文将会基于react实现滚动菜单栏功能。
技术实现
实现效果 点击菜单内容区域会自动滚动到对应卡片。内容区域滑动指定菜单栏会被选中。 ScrollMenu.js
import {useRef, useState} from react;
import ./ScrollMenu.css;export const ScrollMenu ({products}) {// 获取 categoryProductMapconst 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 classNamescroll-menudiv classNamemenu{// 菜单列表categoryList.map((category, index) {return (div className{menu-item ((index current )? -active : )}key{${index}} id{menu-item-${index}}onClick{(event) {onMenuClick(index)}}{category}/div)})}/divdiv classNamecontent ref{contentRef} onScroll{(event) {onContentScroll()}}{categoryList.map((category, index) {// 获取类别商品const productList categoryProductMap.get(category);return (div key{index}div classNamecontent-item-header key{${index}}id{content-item-${index}} style{{height: itemHeight}} {category}/div{productList.map((product,idx) {return div classNamecontent-item-productstyle{{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;