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

React 两行图片列表如何实现方向键直观导航功能

两行flex布局垂直导航实现方案

核心逻辑

你只需要先确定两个基础变量即可实现通用逻辑,不受列表长度变化影响:

  • 单行可容纳元素数量perRow:如果是固定宽度元素,用容器宽度除以单个元素的总宽度(含外边距、内边距)取整即可;如果是固定每行显示数量直接赋值即可,窗口大小变化时可以重新计算适配响应式布局。
  • 当前激活元素的索引currentActiveIndex:注意统一索引起始规则,以下示例以0作为索引起始值。

垂直导航跳转规则:

  • 按下向下方向键:目标索引 = currentActiveIndex + perRow,如果目标索引小于列表总长度,直接激活对应元素;如果目标索引超出总长度,可根据交互需求选择不跳转,或者激活第二行最后一个元素。
  • 按下向上方向键:目标索引 = currentActiveIndex - perRow,如果目标索引大于等于0,直接激活对应元素;如果目标索引小于0,可选择不跳转,或者激活第一行第一个元素。

你提到的从第3个区块跳转到第8个区块的场景,刚好符合单行数量为5的逻辑:3+5=8(如果索引从1开始计数)。

代码示例

// 提前获取DOM元素
const imgItems = document.querySelectorAll('.img-item')
const container = document.querySelector('.img-container')
// 单个元素总宽度,包含你设置的左右margin、padding,按需调整
const singleItemTotalWidth = imgItems[0].offsetWidth + 16
let currentActiveIndex = 0 // 初始激活第一个元素
let perRow = 0

// 计算单行可容纳数量,可在window.resize事件中重新调用适配响应式
function calcPerRow() {
  perRow = Math.floor(container.offsetWidth / singleItemTotalWidth)
}
calcPerRow()

// 方向键监听
document.addEventListener('keydown', (e) => {
  let targetIndex = currentActiveIndex
  switch(e.key) {
    // 原有左右导航逻辑可直接保留
    case 'ArrowLeft':
      targetIndex = Math.max(0, currentActiveIndex - 1)
      break
    case 'ArrowRight':
      targetIndex = Math.min(imgItems.length - 1, currentActiveIndex + 1)
      break
    // 上下导航逻辑
    case 'ArrowDown':
      targetIndex = currentActiveIndex + perRow
      // 超出列表长度时自动调整为最后一个元素,不需要该逻辑可删除此行,直接判断targetIndex >= imgItems.length则不跳转
      targetIndex = Math.min(imgItems.length - 1, targetIndex)
      break
    case 'ArrowUp':
      targetIndex = currentActiveIndex - perRow
      // 索引小于0时自动调整为第一个元素,不需要该逻辑可删除此行,直接判断targetIndex < 0则不跳转
      targetIndex = Math.max(0, targetIndex)
      break
    default:
      return
  }
  // 更新激活状态
  if (targetIndex !== currentActiveIndex) {
    imgItems[currentActiveIndex].classList.remove('active')
    currentActiveIndex = targetIndex
    imgItems[currentActiveIndex].classList.add('active')
    // 如果需要滚动到可视区域可自行加scrollIntoView逻辑
  }
})

非偶数长度适配

如果列表总长度不是偶数,第二行元素数量少于第一行,上述代码已经做了边界兼容,不需要额外调整;如果不需要自动适配到首尾元素,只要在跳转前加边界判断,不符合条件就不执行激活逻辑即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 08:18:03