You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在子菜单打开时保持表格行的Hover状态

问题:子菜单激活时保持表格行Hover效果

我有一个展示设备的表格,鼠标悬停表格行时整行变灰并显示操作按钮,点击按钮弹出子菜单,但光标移到子菜单上时,行的Hover灰色效果就消失了。怎么让子菜单激活(打开)时保持行的Hover样式?

相关代码

App.tsx

import "./styles.css";
import { SubMenu } from "./SubMenu";

const subMenuSlice = <SubMenu />;

const nodes = [
  {
    id: "0",
    name: "Samsung Galaxy",
    subMenu: subMenuSlice
  },
  {
    id: "0",
    name: "Iphone",
    subMenu: subMenuSlice
  }
];

export default function App() {
  return (
    <table>
      <tbody>
        {nodes.map((val, key) => (
          <tr key={key}>
            <td>{val.name}</td>
            <td>{val.subMenu}</td>
          </tr>
        ))}
      </tbody>
    </table>
  );
}

SubMenu.tsx

import { useState } from "react";
import AppsIcon from "@mui/icons-material/Apps";
import * as DropdownMenu from "@radix-ui/react-dropdown-menu";
import "./styles.css";

export const SubMenu = () => {
  const [isOpen, setIsOpen] = useState(false);

  return (
    <DropdownMenu.Root open={isOpen} onOpenChange={setIsOpen}>
      <DropdownMenu.Trigger>
        <AppsIcon className="sss" />
      </DropdownMenu.Trigger>
      <DropdownMenu.Portal>
        <DropdownMenu.Content
          side="bottom"
          sideOffset={-30}
          align="start"
          alignOffset={80}
        >
          <button className="style-button">Edit </button>
          <button className="style-button">Make </button>
          <button className="style-button">Delete </button>
        </DropdownMenu.Content>
      </DropdownMenu.Portal>
    </DropdownMenu.Root>
  );
};

styles.css

.sss {
  visibility: hidden;
}

tr:hover .sss {
  background: gray;
  visibility: visible;
}

tr:hover {
  background: gray;
  visibility: visible;
  pointer-events: initial !important;
}

.style-button:hover {
  background-color: aqua;
}

解决方案

核心思路是通过状态跟踪子菜单的打开状态,给对应表格行添加一个和Hover效果一致的CSS类,让菜单打开时行保持灰色样式。

1. 修改SubMenu组件,传递菜单状态给父组件

给SubMenu添加回调函数,把菜单的打开/关闭状态同步到父组件:

import { useState } from "react";
import AppsIcon from "@mui/icons-material/Apps";
import * as DropdownMenu from "@radix-ui/react-dropdown-menu";
import "./styles.css";

export const SubMenu = ({ onMenuOpen }: { onMenuOpen: (isOpen: boolean) => void }) => {
  const [isOpen, setIsOpen] = useState(false);

  const handleOpenChange = (open: boolean) => {
    setIsOpen(open);
    onMenuOpen(open); // 将状态传递给父组件
  };

  return (
    <DropdownMenu.Root open={isOpen} onOpenChange={handleOpenChange}>
      <DropdownMenu.Trigger>
        <AppsIcon className="sss" />
      </DropdownMenu.Trigger>
      <DropdownMenu.Portal>
        <DropdownMenu.Content
          side="bottom"
          sideOffset={-30}
          align="start"
          alignOffset={80}
        >
          <button className="style-button">Edit </button>
          <button className="style-button">Make </button>
          <button className="style-button">Delete </button>
        </DropdownMenu.Content>
      </DropdownMenu.Portal>
    </DropdownMenu.Root>
  );
};

2. 在父组件中跟踪每行的菜单状态,添加动态类

在App组件中用state存储每行的菜单打开状态,给对应表格行添加row-active类:

import "./styles.css";
import { SubMenu } from "./SubMenu";
import { useState } from "react";

export default function App() {
  const [menuOpenStates, setMenuOpenStates] = useState<Record<number, boolean>>({});

  const handleMenuOpen = (key: number, isOpen: boolean) => {
    setMenuOpenStates(prev => ({ ...prev, [key]: isOpen }));
  };

  const nodes = [
    { id: "0", name: "Samsung Galaxy" },
    { id: "0", name: "Iphone" }
  ];

  return (
    <table>
      <tbody>
        {nodes.map((val, key) => (
          <tr 
            key={key}
            className={menuOpenStates[key] ? "row-active" : ""}
          >
            <td>{val.name}</td>
            <td>
              <SubMenu onMenuOpen={(isOpen) => handleMenuOpen(key, isOpen)} />
            </td>
          </tr>
        ))}
      </tbody>
    </table>
  );
}

3. 修改CSS,让row-active类继承Hover样式

更新styles.css,让row-active类的效果和tr:hover完全一致:

.sss {
  visibility: hidden;
}

tr:hover .sss,
tr.row-active .sss {
  background: gray;
  visibility: visible;
}

tr:hover,
tr.row-active {
  background: gray;
  visibility: visible;
  pointer-events: initial !important;
}

.style-button:hover {
  background-color: aqua;
}

这样当子菜单打开时,对应的表格行会自动加上row-active类,保持和鼠标悬停时一样的灰色样式,直到菜单关闭为止。

内容的提问来源于stack exchange,提问作者Paul

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 13:43:14