[英]show and hide associated sub menu when particular menu is clicked
I am designing a responsive mega navigation bar using reactjs.我正在使用 reactjs 设计一个响应式大型导航栏。 It's working for desktop device but on mobile view, I could not able to show or hide sub menu when its associated parent menu is clicked.它适用于桌面设备,但在移动视图上,当单击其关联的父菜单时,我无法显示或隐藏子菜单。 This is what I am trying to do这就是我想要做的
const menus = [
{ id: 1, name: "Home", link: "/" },
{
id: 3,
name: "New",
children: [{ id: 1, name: "New Arrival", link: "/new" }]
},
{
id: 2,
name: "Shop",
children: [
{
id: 1,
name: "Men's Fashion",
children: [
{
id: 1,
name: "Polo",
link: "/polo"
},
{ id: 2, name: "Tees", link: "/tees" }
]
},
{
id: 2,
name: "Women Fashion",
children: [
{
id: 1,
name: "Shorts",
link: "/shorts"
},
{
id: 2,
name: "Tees",
link: "/women/tees"
}
]
}
]
}
];
const MegaMenu = () => {
const [active, setActive] = React.useState(false);
const [toggle, setToggle] = React.useState(false);
const [activeMenuName, setActiveMenuName] = React.useState("");
const handleMainMenuClick = () => {
setActive(!active);
};
const toggleDrawer = () => {
setToggle(!toggle);
};
const hideSubMenu = () => {
setActive(!active);
};
const handleMenuName = (menuName) => {
setActiveMenuName(menuName);
};
return (
<>
<header className="header">
<div className="container">
<div className="row v-center">
<div className="header-item item-left">
<div className="logo">
<a href="#">Brand</a>
</div>
</div>
{/* menu start here */}
<div className="header-item item-center">
<div
className={`menu-overlay ${toggle ? "active" : ""}`}
onClick={toggleDrawer}
></div>
<nav className={`menu ${toggle ? "active" : ""}`}>
<div className={`mobile-menu-head ${toggle ? "active" : ""}`}>
<div className="go-back" onClick={hideSubMenu}>
Back
</div>
<div className="current-menu-title">{activeMenuName}</div>
<div className="mobile-menu-close" onClick={toggleDrawer}>
×
</div>
</div>
<ul className="menu-main" onClick={handleMainMenuClick}>
{menus.map((menu) => {
return (
<li
key={menu.id}
className={
menu.children ? "menu-item-has-children" : ""
}
onClick={() => handleMenuName(menu.name)}
>
{menu.link ? (
<a href={menu.link}>
{menu.name} <i class="fa fa-angle-down"></i>
</a>
) : (
<a href="#">{menu.name}</a>
)}
{menu.children && (
<div
className={`sub-menu mega-menu mega-menu-column-4 ${
active ? "active" : ""
}`}
>
{menu.children.map((child) => {
return (
<div
className="list-item text-center"
key={child.id}
>
<a href="#">
<img src="img/p1.jpg" alt="new Product" />
<h4 className="title">{child.name}</h4>
</a>
</div>
);
})}
</div>
)}
</li>
);
})}
</ul>
</nav>
</div>
<div className="header-item item-right">
<a href="#">
<i className="fas fa-search"></i>
</a>
<a href="#">
<i className="far fa-heart"></i>
</a>
<a href="#">
<i className="fas fa-shopping-cart"></i>
</a>
{/* mobile menu trigger */}
<div className="mobile-menu-trigger" onClick={toggleDrawer}>
<span></span>
</div>
</div>
</div>
</div>
</header>
</>
);
};
export default MegaMenu;
I have a code on sandbox as well and here it is我在沙盒上也有一个代码,在这里
https://codesandbox.io/s/weathered-resonance-9n2hr?file=/src/mega-menu/index.js:50-4734 https://codesandbox.io/s/weathered-resonance-9n2hr?file=/src/mega-menu/index.js:50-4734
You should set active
only to the activeMenuName
that is clicked.您应该仅将active
设置为单击的activeMenuName
。 Also when click go back
you should reset activeMenuName
to the default state.同样,当单击go back
时,您应该将activeMenuName
重置为默认 state。 Also, I check if toggle
is enabled so only onClick
events are enabled and vice versa.此外,我检查是否启用了toggle
,因此仅启用了onClick
事件,反之亦然。
Check my code it's tested.检查我的代码,它已经过测试。
const MegaMenu = () => {
const [active, setActive] = React.useState(false);
const [toggle, setToggle] = React.useState(false);
const [activeMenuName, setActiveMenuName] = React.useState("");
const handleMainMenuClick = () => {
setActive(!active);
};
const toggleDrawer = () => {
setActiveMenuName("");
setToggle(!toggle);
};
const hideSubMenu = () => {
setActiveMenuName("");
};
const handleMenuName = (menuName) => {
setActiveMenuName(menuName);
};
const renderLiComp = (menu) =>{
if(toggle){
return <li
key={menu.id}
className={ menu.children ? "menu-item-has-children" : "" }
onClick={() =>handleMenuName(menu.name)}
>
{menu.link
? (<a href={menu.link}>{menu.name} <i className="fa fa-angle-down"></i></a>)
: (<a href="#">{menu.name}</a>)}
{activeMenuName && getSelectedChildren()}
</li>;
}else{
return <li
key={menu.id}
className={ menu.children ? "menu-item-has-children" : "" }
onMouseEnter={()=>handleMenuName(menu.name)}
>
{menu.link
? (<a href={menu.link}>{menu.name} <i className="fa fa-angle-down"></i></a>)
: (<a href="#">{menu.name}</a>)}
{activeMenuName && getSelectedChildren()}
</li>;
}
}
const renderListElements = () =>{
return menus.map(renderLiComp);
}
const renderChildren = (childs) =>{
const children = childs.map(x =>
<div className="list-item text-center" key={x.id}>
<a href="#"><img src="img/p1.jpg" alt="new Product" />
<h4 className="title">{x.name}</h4>
</a>
</div>
);
return children;
}
const getSelectedChildren = () =>{
return menus.map(x => {
let selected;
if(x.name === activeMenuName){
if(x.children){
selected = <div key={x.id} className='sub-menu mega-menu mega-menu-column-4 active'>{renderChildren(x.children)}</div>;
}else{
selected = <div key={x.id} className='sub-menu mega-menu mega-menu-column-4 active'></div>;
}
}
return selected;
});
}
return (
<>
<header className="header">
<div className="container">
<div className="row v-center">
<div className="header-item item-left">
<div className="logo">
<a href="#">Brand</a>
</div>
</div>
{/* menu start here */}
<div className="header-item item-center">
<div
className={`menu-overlay ${toggle ? "active" : ""}`}
onClick={toggleDrawer}
></div>
<nav className={`menu ${toggle ? "active" : ""}`}>
<div className={`mobile-menu-head ${toggle ? "active" : ""}`}>
<div className="go-back" onClick={hideSubMenu}>
Back
</div>
<div className="current-menu-title">{activeMenuName}</div>
<div className="mobile-menu-close" onClick={toggleDrawer}>
×
</div>
</div>
<ul className="menu-main" onClick={handleMainMenuClick}>
{renderListElements()}
</ul>
</nav>
</div>
The sandbox Link https://codesandbox.io/s/nifty-cloud-kuryf?file=/src/mega-menu/index.js沙盒链接https://codesandbox.io/s/nifty-cloud-kuryf?file=/src/mega-menu/index.js
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.