如何在 React 中像 google 驱动器这样的响应式卡片网格上进行箭头键导航?

How to make arrow key navigation on responsive card grid like google drive in React?

我已经尝试在所有 4 个方向上实现箭头键导航。我能够使用 nextSiblingpreviousSibling 实现 2 个方向 leftright。但没有找到任何方法来获得高于和低于 divs。我见过很多在卡片网格布局上使用箭头键导航的示例,但发现没有一个采用响应式设计。当您有响应式支持时,每行中的卡片数量会发生变化。在我们的例子中,我们有一个 div 和 wrap 来创建网格。我见过像 Google drive 这样的应用程序,它们具有响应支持和箭头键导航。 Sample

如果您确定所有卡片的宽度都相同,您可以采用以下方法:
您可以使用它们的 x 和 y 坐标找到上方或下方的元素,您可以使用 Element.getBoundingClientRect() , window.scrollX and window.scrollY 方法获得这些元素。

继续您的 sample,
将 getRect() 方法添加到您的布局组件以获取 x 和 y 坐标。

getRect = (id) => {
    const el = document.getElementById(id);
    const rect = el.getBoundingClientRect();
    const x = rect.left + window.scrollX;
    const y = rect.top + window.scrollY;
    return { el, x, y };
  };

现在将 ARROW_UPARROW_DOWN 键的条件添加到 handleKeyPress() 方法

 else if (e.key === NAVIGATION_KEYS.ARROW_UP) {
      const { x, y } = this.getRect(selected);

      // loop back in the list and select the first element
      // that is above the current selected element and has the same x coordinate
      for (let i = list.indexOf(selected) - 1; i >= 0; i--) {
        const { el, x: tx, y: ty } = this.getRect(list[i]);

        if (x === tx && y > ty) {
          this.setState({
            selected: list[i]
          });
          el.scrollIntoView(); // scrolls the element into view, try removing it to see what it does
          break;
        }
      }
    } else if (e.key === NAVIGATION_KEYS.ARROW_DOWN) {
      const { x, y } = this.getRect(selected);

      // loop forward in the list and select the first element
      // that is below the current selected element and has the same x coordinate
      for (let i = list.indexOf(selected) + 1; i < list.length; i++) {
        const { el, x: tx, y: ty } = this.getRect(list[i]);

        if (x === tx && y < ty) {
          this.setState({
            selected: list[i]
          });
          el.scrollIntoView(); // scrolls the element into view, try removing it to see what it does
          break;
        }
      }
    }

如果你想要流畅的滚动效果可以添加下面的css

html {
  scroll-behaviour: smooth;
}

我加了注释解释,有不懂的地方可以问

这是一个 工作示例 从你的 sample

分叉和扩展