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

如何实现英雄图片可拖拽放置到等级图片对应区域的功能

实现思路
  • 核心用原生HTML5 Drag & Drop API实现,不需要引入额外第三方库,代码量少易维护
  • 先调整等级区域结构:给每个等级图片套独立父容器,父容器内新增专门用来放置英雄的区域,避免拖拽放置时打乱原有等级图布局
  • 绑定三类核心拖拽事件即可完成基础功能:
    • dragstart:英雄图片开始拖拽时,存储当前拖拽英雄的图片信息
    • dragover:等级放置区域监听该事件并阻止默认行为,允许元素被放置到当前区域
    • drop:松开鼠标放置时,读取之前存储的英雄信息,将英雄图片插入到当前放置区域
代码示例

1. 调整后的HTML(仅修改.place部分,其他.champs部分保持你原有代码不变)

<div class="place">
  <!-- 每个等级包成独立容器 -->
  <div class="rank-item">
    <img src="images/S.jpg" alt="S">
    <div class="champ-container"></div> <!-- 专门放拖拽进来的英雄 -->
  </div>
  <div class="rank-item">
    <img src="images/A.jpg" alt="A">
    <div class="champ-container"></div>
  </div>
  <div class="rank-item">
    <img src="images/B.jpg" alt="B">
    <div class="champ-container"></div>
  </div>
  <div class="rank-item">
    <img src="images/C.jpg" alt="C">
    <div class="champ-container"></div>
  </div>
  <div class="rank-item">
    <img src="images/D.jpg" alt="D">
    <div class="champ-container"></div>
  </div>
  <div class="rank-item">
    <img src="images/E.jpg" alt="E">
    <div class="champ-container"></div>
  </div>
  <div class="rank-item">
    <img src="images/F.jpg" alt="F">
    <div class="champ-container"></div>
  </div>
  <div class="rank-item">
    <img src="images/Troll.jpg" alt="Troll">
    <div class="champ-container"></div>
  </div>
</div>

2. 基础排版CSS(可根据自己的页面风格调整)

.rank-item {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  margin: 0 10px 20px 0;
  vertical-align: top;
}
.champ-container {
  min-width: 100px;
  min-height: 100px;
  border: 2px dashed #ccc;
  margin-top: 8px;
  padding: 4px;
}
/* 拖拽到容器上方时高亮 */
.champ-container.drag-over {
  border-color: #2ecc71;
  background-color: rgba(46, 204, 113, 0.1);
}
/* 拖拽中的英雄半透明 */
.champs img.dragging {
  opacity: 0.5;
}

3. JavaScript实现代码(直接复制到你的JS文件中即可)

// 存储当前拖拽的英雄图片信息
let draggedChamp = null;

// 给所有英雄图片绑定拖拽开始事件
document.querySelectorAll('.champs img').forEach(champImg => {
  champImg.addEventListener('dragstart', e => {
    draggedChamp = {
      src: champImg.src,
      alt: champImg.alt
    };
    champImg.classList.add('dragging');
    // 存储数据方便事件传递
    e.dataTransfer.setData('text/plain', JSON.stringify(draggedChamp));
  });

  champImg.addEventListener('dragend', () => {
    champImg.classList.remove('dragging');
    draggedChamp = null;
  });
});

// 给所有等级下的放置容器绑定事件
document.querySelectorAll('.champ-container').forEach(container => {
  // 拖拽经过容器时阻止默认行为,允许放置
  container.addEventListener('dragover', e => {
    e.preventDefault();
    container.classList.add('drag-over');
  });

  // 拖拽离开容器时移除高亮
  container.addEventListener('dragleave', () => {
    container.classList.remove('drag-over');
  });

  // 放置英雄
  container.addEventListener('drop', e => {
    e.preventDefault();
    container.classList.remove('drag-over');
    // 读取拖拽数据
    const champData = JSON.parse(e.dataTransfer.getData('text/plain'));
    // 创建新的英雄图片插入到容器里
    const newChampImg = document.createElement('img');
    newChampImg.src = champData.src;
    newChampImg.alt = champData.alt;
    newChampImg.width = 100;
    // 可选:允许已经放在等级里的英雄再次被拖拽调整位置
    newChampImg.draggable = true;
    newChampImg.addEventListener('dragstart', e => {
      draggedChamp = {
        src: newChampImg.src,
        alt: newChampImg.alt
      };
      newChampImg.classList.add('dragging');
      e.dataTransfer.setData('text/plain', JSON.stringify(draggedChamp));
      // 拖拽的时候把原图片删掉,实现移动效果
      setTimeout(() => newChampImg.remove(), 0);
    });
    container.appendChild(newChampImg);
  });
});
功能扩展说明

如果需要更多功能可以自行扩展:

  • 限制每个等级区域放置的英雄数量
  • 支持拖拽英雄回英雄列表移除
  • 添加英雄排序、删除按钮
  • 存储当前的tier list配置到本地缓存,刷新页面不丢失

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 18:27:06