【问题标题】:On Hover Only Show Element Related To Menu仅悬停时显示与菜单相关的元素
【发布时间】:2020-05-20 15:09:11
【问题描述】:

在我的 React 项目中,我有一个包含 2 个主列表/导航项的菜单,并且希望在悬停时显示一个元素,并且当用户悬停在子菜单上时也保持可见。我可以使用 css hover 和设置 className based boolean of a state 来完成这项工作。

问题是,当用户将鼠标悬停在子菜单上时,如何显示与该菜单相关的元素?现在,当子菜单悬停时,这两个元素都会显示。我正在使用.map 填充菜单和子菜单项,所以想知道是否有我传入的道具来控制它?

代码如下:

import React, { useState } from "react";
import styles from "./nav.module.scss";
import "../../styles/main.scss";

const Nav = ({
  navItems = [
    {
      id: "",
      label: "",
      subMenu: [{}]
    }
  ]
}) => {
  const [ballColor, setBallColor] = useState();
  const [showBall, setShowBall] = useState(false);

  const handleHover = () => {
    setShowBall(!showBall);
  };

  return (
    <>
      <nav>
        {/* Start of Menu Items */}
        <div className={styles.menuItemsContainer}>
          <ul className={styles.navUl}>
            {navItems.map(item => (
              <li key={item.id}>
                <a href="https://www.google.com">
                  <div
                    className={
                      showBall
                        ? `${styles.ball} ${styles.showBall} ${
                            styles[ballColor]
                          }`
                        : `${styles.ball} ${styles[ballColor]}`
                    }
                  />
                  {item.label}
                </a>
                <ul
                  className={
                    item.subMenu.length === 0
                      ? `${styles.noDisplay}`
                      : `${styles.display}`
                  }
                  onMouseEnter={handleHover}
                  onMouseLeave={handleHover}
                >
                  {item.subMenu.map(subItem => (
                    <li
                      key={subItem.id}
                      className={styles[subItem.class]}
                      onMouseOver={() => {
                        setBallColor(subItem.ballColor);
                      }}
                      onMouseLeave={() => setBallColor(null)}
                    >
                      {subItem.item}
                    </li>
                  ))}
                </ul>
              </li>
            ))}
          </ul>
        </div>
        {/* End of Menu Items */}
      </nav>
    </>
  );
};

export default Nav;

参考sandbox

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    你想要的是一组颜色:每个主菜单一个颜色。

    以下代码是实现它的一种方法,我不喜欢循环中的所有这些循环,所以它只是一种向您展示如何处理它的方法,但可能不是最好的:

    import React, { useState } from "react";
    import styles from "./nav.module.scss";
    import "../../styles/main.scss";
    
    const Nav = ({
      navItems = [
        {
          id: "",
          label: "",
          subMenu: [{}]
        }
      ]
    }) => {
      const [ballColors, setBallColor] = useState(["#fff", "#fff"]);
      const [showBalls, setShowBall] = useState([false, false]);
    
      const handleHover = i => {
        setShowBall([...showBalls].map((bool, j) => (i === j ? !bool : bool)));
      };
    
      return (
        <>
          <nav>
            {/* Start of Menu Items */}
            <div className={styles.menuItemsContainer}>
              <ul className={styles.navUl}>
                {navItems.map((item, i) => (
                  <li key={item.id}>
                    <a href="https://www.google.com">
                      <div
                        className={
                          showBalls[i]
                            ? `${styles.ball} ${styles.showBall} ${
                                styles[ballColors[i]]
                              }`
                            : `${styles.ball} ${styles[ballColors[i]]}`
                        }
                      />
                      {item.label}
                    </a>
                    <ul
                      className={
                        item.subMenu.length === 0
                          ? `${styles.noDisplay}`
                          : `${styles.display}`
                      }
                      onMouseEnter={() => handleHover(i)}
                      onMouseLeave={() => handleHover(i)}
                    >
                      {item.subMenu.map((subItem, j) => (
                        <li
                          key={subItem.id}
                          className={styles[subItem.class]}
                          onMouseOver={() => {
                            setBallColor(
                              [...ballColors].map((color, k) =>
                                i === k ? subItem.ballColor : color
                              )
                            );
                          }}
                          onMouseLeave={() =>
                            setBallColor(
                              [...ballColors].map((color, k) =>
                                i === k ? "#fff" : color
                              ),
                              i
                            )
                          }
                        >
                          {subItem.item}
                        </li>
                      ))}
                    </ul>
                  </li>
                ))}
              </ul>
            </div>
            {/* End of Menu Items */}
          </nav>
          ballColors: {ballColors.join(" ")}
        </>
      );
    };
    
    export default Nav;
    

    这里是 a fork of your codepen 作为该解决方案的演示。

    【讨论】:

    • 我不担心颜色,只是当您将鼠标悬停在子菜单上时,大的半圆会出现在另一个导航项的顶部。
    • 同样的事情:你想要一个布尔数组...更新。
    • 好的,有道理。我会回顾一下,但这看起来很有希望。
    • 我想问你handleHover函数背后的逻辑。如果我错了,请纠正我,但似乎i 将始终等于j,它返回true,它将showBalls 值从false 切换到true,反之亦然?
    • 为什么 i 总是等于 j ?仅当只有一个主菜单时才会如此。
    猜你喜欢
    • 2016-04-24
    • 2019-05-22
    • 2014-05-18
    • 2022-01-20
    • 2020-07-15
    • 1970-01-01
    • 2019-10-30
    • 1970-01-01
    相关资源
    最近更新 更多