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

基于Flex的5×5网格交互优化需求:点击后聚焦9个元素

嘿,我来帮你搞定这个5×5 Flex网格的交互升级!针对你提到的需求,我整理了清晰的实现思路和可直接用的代码方案,咱们一步步来:

核心需求梳理

先把要做的效果明确下来:

  • 初始是5×5的Flex网格,中间3×3的元素支持点击
  • 点击元素后,该元素变红并调整宽高,其余元素适配它的尺寸
  • 新增关键交互:点击这个红色中心元素后,只显示它和周围8个元素(共9个),剩下的16个元素直接隐藏
  • 切换点击其他中心元素时,视图同步切换成当前点击元素+它的8个邻居,其余元素消失

实现思路拆解

要实现这个效果,核心是搞定「元素索引管理」和「显示状态控制」:

  1. 给每个元素加唯一索引:把5×5网格的25个元素按从左到右、从上到下的顺序标上0-24的索引,这样能快速算出任意元素的周围邻居位置
  2. 点击事件处理逻辑:
    • 点击中间3×3的元素时,先把它标记为「当前中心」,加上红色背景和宽高样式
    • 根据中心元素的索引,计算出它周围8个邻居的索引(中间3×3的元素的邻居肯定都在5×5网格范围内,不用担心越界)
  3. 显示/隐藏控制:给元素加.visible和.hidden类,点击后只给中心+邻居加.visible,其余加.hidden,Flex布局会自动适配剩下的元素排列
  4. Flex布局适配:切换到9元素视图时,调整元素的宽度占比,让它们刚好排成3×3的网格

具体代码实现

HTML结构

给每个网格元素加上data-index属性存索引,中间3×3的元素加clickable类标记可点击:

<div class="grid-container">
  <!-- 第0行 -->
  <div class="grid-item" data-index="0"></div>
  <div class="grid-item" data-index="1"></div>
  <div class="grid-item" data-index="2"></div>
  <div class="grid-item" data-index="3"></div>
  <div class="grid-item" data-index="4"></div>
  <!-- 第1行 -->
  <div class="grid-item" data-index="5"></div>
  <div class="grid-item clickable" data-index="6"></div>
  <div class="grid-item clickable" data-index="7"></div>
  <div class="grid-item clickable" data-index="8"></div>
  <div class="grid-item" data-index="9"></div>
  <!-- 第2行 -->
  <div class="grid-item" data-index="10"></div>
  <div class="grid-item clickable" data-index="11"></div>
  <div class="grid-item clickable" data-index="12"></div>
  <div class="grid-item clickable" data-index="13"></div>
  <div class="grid-item" data-index="14"></div>
  <!-- 第3行 -->
  <div class="grid-item" data-index="15"></div>
  <div class="grid-item clickable" data-index="16"></div>
  <div class="grid-item clickable" data-index="17"></div>
  <div class="grid-item clickable" data-index="18"></div>
  <div class="grid-item" data-index="19"></div>
  <!-- 第4行 -->
  <div class="grid-item" data-index="20"></div>
  <div class="grid-item" data-index="21"></div>
  <div class="grid-item" data-index="22"></div>
  <div class="grid-item" data-index="23"></div>
  <div class="grid-item" data-index="24"></div>
</div>

CSS样式

设置基础Flex布局,加上点击元素的红色样式、显示/隐藏类,还有切换到3×3视图时的适配样式:

.grid-container {
  display: flex;
  flex-wrap: wrap;
  width: 500px; /* 可根据需求调整总宽度 */
  gap: 2px; /* 可选,给元素加间距 */
}

.grid-item {
  width: 20%; /* 5×5网格,每个元素占20%宽度 */
  height: 100px;
  border: 1px solid #ddd;
  transition: all 0.3s ease;
}

/* 标记可点击元素 */
.grid-item.clickable {
  cursor: pointer;
  background-color: #f0f0f0;
}

/* 点击后的中心元素样式 */
.grid-item.active {
  background-color: red;
  width: 30%;
  height: 120px;
}

/* 隐藏元素 */
.grid-item.hidden {
  display: none;
}

/* 3×3视图时的容器样式 */
.grid-container.expanded {
  /* 保持总宽度不变,让元素排成3×3 */
}
.grid-container.expanded .grid-item.visible {
  width: calc(100% / 3 - 4px); /* 减去gap的宽度 */
  height: 150px; /* 可选,调整高度适配 */
}

JavaScript逻辑

实现点击事件、索引计算、状态控制:

const gridContainer = document.querySelector('.grid-container');
const gridItems = document.querySelectorAll('.grid-item');
const clickableItems = document.querySelectorAll('.grid-item.clickable');

// 计算中心元素的所有邻居索引
function getSurroundingIndexes(centerIndex) {
  const visibleIndexes = [centerIndex];
  const row = Math.floor(centerIndex / 5); // 中心元素所在行
  const col = centerIndex % 5; // 中心元素所在列

  // 8个方向:左上、上、右上、左、右、左下、下、右下
  const directions = [
    [-1, -1], [-1, 0], [-1, 1],
    [0, -1],          [0, 1],
    [1, -1],  [1, 0], [1, 1]
  ];

  // 遍历每个方向,计算邻居索引
  directions.forEach(([rowOffset, colOffset]) => {
    const newRow = row + rowOffset;
    const newCol = col + colOffset;
    // 确保邻居在5×5网格范围内
    if (newRow >= 0 && newRow < 5 && newCol >= 0 && newCol < 5) {
      const neighborIndex = newRow * 5 + newCol;
      visibleIndexes.push(neighborIndex);
    }
  });

  return visibleIndexes;
}

// 重置所有元素的状态
function resetGridState() {
  gridItems.forEach(item => {
    item.classList.remove('active', 'visible', 'hidden');
  });
  gridContainer.classList.remove('expanded');
}

// 绑定点击事件
clickableItems.forEach(item => {
  item.addEventListener('click', () => {
    // 先重置之前的状态
    resetGridState();

    // 获取当前点击元素的索引
    const centerIndex = parseInt(item.dataset.index);
    // 标记为活跃中心元素
    item.classList.add('active');

    // 获取要显示的元素索引
    const visibleIndexes = getSurroundingIndexes(centerIndex);

    // 设置显示/隐藏状态
    gridItems.forEach((gridItem, index) => {
      if (visibleIndexes.includes(index)) {
        gridItem.classList.add('visible');
      } else {
        gridItem.classList.add('hidden');
      }
    });

    // 切换到3×3视图的布局
    gridContainer.classList.add('expanded');
  });
});

关键细节说明

  • 索引计算:通过行和列的偏移量快速找到邻居,逻辑简单且不容易出错,哪怕以后网格大小变了,只需要改行数的数值就行
  • 状态重置:每次点击新元素前都重置所有状态,避免之前的样式残留导致混乱
  • Flex适配:通过给容器加.expanded类,动态调整元素宽度,让9个元素刚好排成3×3,完美适配视图切换

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 03:43:01