【问题标题】:How to hover over multiple table cells?如何将鼠标悬停在多个表格单元格上?
【发布时间】:2020-09-07 21:32:15
【问题描述】:

有没有办法让多个相邻的单元格在一个单元格悬停时改变颜色?有没有办法使这种动态变化(例如,也会改变颜色的相邻单元格的数量可以变化)?

代码如下:

我在 React 中有一个表格,代码如下:

<TableBody>
<TableRow>{tableRowGen()}</TableRow>
</TableBody>

tableRowGen函数的代码如下:

const tableRowGen = () => {
    let cells = [];

    for (var i = 0; i < columnNumber; i++) {
      cells.push(
        <TableCell
          className={classes.td}
          onMouseEnter={() => {
            console.log("hi!");
          }}
          align="center"
        >
          {i}
        </TableCell>
      );
    }
    console.log(cells);
    return cells;
  };

目前,我有一个表格单元格 (td) 的类,它将悬停颜色更改为红色:

td: {
    ...
    "&:hover": {
      background: "#f00",
    },
  },

示例如下:

当前代码是这样的:

但是当只悬停在 3 上时,是否可以使 4 和 5 变为红色? (如下图)

编辑: 新增tableRowGen功能码:

const tableRowGen = () => {
    let cells = [];

    for (var i = 0; i < columnNumber; i++) {
      cells.push(
        <TableCell
          // className={classes.td}
          align="center"
          onMouseEnter={() => onMouseEnter(i)}
          onMouseLeave={onMouseLeave}
          className={Math.abs(hoveredCell - i) <= 14 ? classes.td : ""}
        >
          {i}
        </TableCell>
      );
    }
    return cells;
  };

根据建议的其他代码:

const [hoveredCell, setHoveredCell] = React.useState(null);

  const onMouseEnter = React.useCallback((index) => {
    setHoveredCell(index);
  }, []);

  const onMouseLeave = React.useCallback(() => {
    setHoveredCell(null);
  }, []);

【问题讨论】:

    标签: javascript css reactjs material-ui


    【解决方案1】:

    你可以这样做。

    创建一个单独的组件来处理每个TableRowhover 事件。

    const useStyles = makeStyles({
      highlighted: {
        background: "#f00"
      }
    });
    
    const MyTableRow = () => {
      const classes = useStyles();
      const columnNumber = 10;
    
      // the index of the cell that will trigger if should highlight on hover
      const targetIndex = 3;
    
      // indeces to highlight
      const indicesToHighlight = [3, 4, 5, 7, 9];
    
      // when set to true, will highlight
      const [highlight, setHighlight] = React.useState(false);
    
      function onMouseEnter(event) {
        setHighlight(parseInt(event.target.dataset.index) === targetIndex);
      }
    
      function onMouseLeave() {
        setHighlight(false);
      }
    
      const cells = [...Array(columnNumber)].map((_, i) => {
        const shouldHighlighted = indicesToHighlight.includes(i);
        const className = highlight && shouldHighlighted && classes.highlighted;
    
        return (
          <TableCell key={i} data-index={i} align="center" className={className}>
            {i}
          </TableCell>
        );
      });
    
      return (
        <TableRow onMouseMove={onMouseEnter} onMouseLeave={onMouseLeave}>
          {cells}
        </TableRow>
      );
    };
    


    请注意,我使用onMouseMove 而不是onMouseEnter - onMouseEnter 只会在行悬停时触发一次,这与onMouseMove 不同,它会在每次移动鼠标指针时触发event

    另外,我不想在每个单元格上都附加event listener,那样会很昂贵。我正在使用event delegation 技术,因此只有一个元素会监听该事件。

    【讨论】:

    • 谢谢你!有没有办法不预先定义将突出显示的索引,而只是突出显示相邻的单元格(例如,如果我将鼠标悬停在 1 上,那么 2 和 3 也应该突出显示,或者如果我将鼠标悬停在 6 上,那么 7 和 8 应该也被突出显示)?
    • 好的,请稍等。
    • 我将演示更新为具有MyTableRowV2 组件。
    • 谢谢!你是救生员。
    • 很高兴我能帮忙?
    【解决方案2】:

    您绝对可以使用 javascript 执行此操作,在用户悬停时添加或删除 css 类。也可以仅使用带有sibling selector 的 css 来执行此类操作。这是一个简单的例子:

    td:hover {
      background-color: red;
    }
    
    td:hover + td {
      background-color: red;
    }
    
    td:hover + td + td {
      background-color: red;
    }
    <table>
      <tbody>
        <tr>
          <td>1,1</td>
          <td>1,2</td>
          <td>1,3</td>
          <td>1,4</td>
        </tr>
        <tr>
          <td>2,1</td>
          <td>2,2</td>
          <td>2,3</td>
          <td>2,4</td>
        </tr>
      </tbody>
    <table>

    这是静态版本——如果你想让单元格的数量是动态的,你需要使用 javascript。

    【讨论】:

    • 不幸的是,对于我的用例来说,静态可能很难实现,因此使用 java 脚本是最好的方法。但是,我不太清楚如何处理它 - 我已经用其他答案的建议更新了我的原始帖子,但它仍然不起作用。
    【解决方案3】:

    使用 CSS 只能突出显示悬停旁边的单元格:

    td:hover, td:hover + td {
      background-color: red;
    }
    

    所以很可能你必须使用 JS 来完成它。在这种情况下,您必须检测悬停。 然后您需要根据hoveredCell 确定要突出显示的单元格。例如,您只想突出显示直接相邻的那些。如果单元格满足条件,您应该添加类:

    const [hoveredCell, setHoveredCell] = useState<number | null>(null);
    
    const onMouseEnter = React.useCallback((index) => {
        setHoveredCell(index);
    }, []);
    
    const onMouseLeave = React.useCallback(() => {
        setHoveredCell(null);
    }, []);
    
    <TableCell
      onMouseEnter={() => onMouseEnter(index)}
      onMouseLeave={onMouseLeave}
      className={Math.abs(hoveredCell - index) <= 1 ? classes.hovered : ''}
    >
    

    条件:Math.abs(hoveredCell - index) &lt;= 1 可以提取为hoveredCellindex 上的函数,并通过props 进行自定义。或者您可以将1 更改为任意数量的单元格

    【讨论】:

    • 我已经按照你说的做了,但是好像没有用,你能看到我做错了什么吗?我已经编辑了我的原始帖子以反映更改。
    猜你喜欢
    • 2010-11-22
    • 1970-01-01
    • 2016-09-28
    • 1970-01-01
    • 1970-01-01
    • 2019-12-13
    • 2010-10-10
    • 2012-07-23
    • 2014-03-27
    相关资源
    最近更新 更多