如何在网页中实现国际象棋棋子的拖拽与格点吸附功能

酷宇同学_3914

酷宇同学_3914

2026-03-29

180人浏览

原创

如何在网页中实现国际象棋棋子的拖拽与格点吸附功能

本文详解如何使用原生 HTML/CSS/JavaScript 构建支持拖拽、自动对齐棋盘格的响应式国际象棋界面,摒弃传统 布局,采用语义化 结构与现代 CSS Grid + drag-and-drop API 实现高可控性交互。

本文详解如何使用原生 html/css/javascript 构建支持拖拽、自动对齐棋盘格的响应式国际象棋界面,摒弃传统 `

` 布局,采用语义化 `
` 结构与现代 CSS Grid + `drag-and-drop` API 实现高可控性交互。

实现可拖拽且能精准吸附到棋盘格的国际象棋界面,关键在于结构解耦与交互控制权收归前端逻辑。使用

会严重限制元素定位、事件绑定与视觉层叠(z-index),而
配合 CSS Grid 或绝对定位可完全掌控每个格子与棋子的位置、状态和行为。

以下是一个轻量、可运行的完整实现方案(无需外部依赖):

✅ 核心思路

  • 棋盘用 display: grid 布局,8×8 网格,每格尺寸统一(如 60px);
  • 棋子为独立
    ,内嵌 Unicode 棋子符号(或 img 标签);
  • 利用 HTML5 draggable="true" + dragstart / dragover / drop 事件实现拖放;
  • 在 drop 时通过坐标计算目标格子索引,将棋子 DOM 节点移动至对应格子内部,实现“吸附”效果。
  • ? 示例代码(精简可运行版)

    
    
      <meta charset="UTF-8"><title>可拖拽国际象棋棋盘</title><style>
        .chessboard {
          display: grid;
          grid-template-columns: repeat(8, 60px);
          grid-template-rows: repeat(8, 60px);
          width: 480px;
          height: 480px;
          margin: 20px auto;
          border: 2px solid #333;
          box-shadow: 0 0 12px rgba(0,0,0,0.2);
        }
        .cell {
          display: flex;
          align-items: center;
          justify-content: center;
          font-size: 40px;
          user-select: none;
          cursor: default;
        }
        .cell.light { background-color: #f0d9b5; }
        .cell.dark  { background-color: #b58863; }
        .piece {
          width: 100%;
          height: 100%;
          display: flex;
          align-items: center;
          justify-content: center;
          font-size: 42px;
          cursor: grab;
          z-index: 10;
          transition: transform 0.15s ease;
        }
        .piece:active { cursor: grabbing; transform: scale(0.95); }
        .piece.white { color: #222; }
        .piece.black { color: #fff; text-shadow: 1px 1px 2px #000; }
      </style><div class="chessboard" id="board"></div>
    
    <script>
      const board = document.getElementById('board');
      const pieces = [
        ['♜', '♞', '♝', '♛', '♚', '♝', '♞', '♜'],
        ['♟', '♟', '♟', '♟', '♟', '♟', '♟', '♟'],
        ['', '', '', '', '', '', '', ''],
        ['', '', '', '', '', '', '', ''],
        ['', '', '', '', '', '', '', ''],
        ['', '', '', '', '', '', '', ''],
        ['♙', '♙', '♙', '♙', '♙', '♙', '♙', '♙'],
        ['♖', '♘', '♗', '♕', '♔', '♗', '♘', '♖']
      ];
    
      // 渲染棋盘与初始棋子
      for (let row = 0; row < 8; row++) {
        for (let col = 0; col < 8; col++) {
          const cell = document.createElement('div');
          cell.className = `cell ${(row + col) % 2 === 0 ? 'light' : 'dark'}`;
          cell.dataset.row = row;
          cell.dataset.col = col;
    
          const pieceChar = pieces[row][col];
          if (pieceChar) {
            const piece = document.createElement('div');
            piece.className = `piece ${row < 2 ? 'black' : 'white'}`;
            piece.draggable = true;
            piece.textContent = pieceChar;
            piece.dataset.row = row;
            piece.dataset.col = col;
            piece.addEventListener('dragstart', handleDragStart);
            cell.appendChild(piece);
          }
    
          board.appendChild(cell);
        }
      }
    
      // 拖拽逻辑
      function handleDragStart(e) {
        e.dataTransfer.setData('text/plain', `${e.target.dataset.row},${e.target.dataset.col}`);
        e.dataTransfer.effectAllowed = 'move';
      }
    
      board.addEventListener('dragover', e => e.preventDefault()); // 必须阻止默认行为才能触发 drop
    
      board.addEventListener('drop', e => {
        e.preventDefault();
        const [srcRow, srcCol] = e.dataTransfer.getData('text/plain').split(',').map(Number);
        const targetCell = e.target.closest('.cell');
        if (!targetCell) return;
    
        const dstRow = +targetCell.dataset.row;
        const dstCol = +targetCell.dataset.col;
    
        // 移动棋子:从原格移除,插入目标格
        const piece = board.querySelector(`[data-row="${srcRow}"][data-col="${srcCol}"]`);
        if (piece && targetCell.children.length === 0) {
          targetCell.appendChild(piece);
          piece.dataset.row = dstRow;
          piece.dataset.col = dstCol;
          // 可选:添加视觉反馈
          targetCell.style.backgroundColor = '#aaffaa';
          setTimeout(() => {
            targetCell.style.backgroundColor = '';
          }, 300);
        }
      });
    </script>

    ⚠️ 关键注意事项

    • 必须调用 e.preventDefault():在 dragover 事件中,否则 drop 事件不会触发;
    • 避免嵌套 draggable 元素:确保 .piece 是直接子元素,且 .cell 不设 draggable="true";
    • 坐标管理需同步更新:每次移动后务必更新 dataset.row/col,为后续合法走法校验打下基础;
    • 移动端兼容性:原生 drag API 在 iOS/Android 上支持有限;如需全平台支持,建议改用 Pointer Events 或第三方库(如 interact.js);
    • 无障碍友好:为 .piece 添加 role="img" 和 aria-label(如 aria-label="白方车"),提升可访问性。

    ✅ 后续扩展建议

    • 引入棋子颜色标识与选中高亮(:focus-within 或 JS 状态管理);
    • 添加“撤销上一步”与“重置棋盘”按钮;
    • 封装为 Class(如 ChessBoard),支持初始化配置与事件钩子(onMove, onInvalidDrop);
    • 结合 FEN 字符串解析,实现棋局持久化与加载。

    该方案兼顾简洁性与可维护性,是构建专业级网页象棋应用的理想起点——拖拽即所见,吸附即所达。

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
html版权符号
html版权符号

html版权符号是“©”,可以在html源文件中直接输入或者从word中复制粘贴过来,php中文网还为大家带来html的相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

2023.06.14

6775

7

html在线编辑器
html在线编辑器

html在线编辑器是用于在线编辑的工具,编辑的内容是基于HTML的文档。它经常被应用于留言板留言、论坛发贴、Blog编写日志或等需要用户输入普通HTML的地方,是Web应用的常用模块之一。php中文网为大家带来了html在线编辑器的相关教程、以及相关文章等内容,供大家免费下载使用。

2023.06.21

3772

4

html网页制作
html网页制作

html网页制作是指使用超文本标记语言来设计和创建网页的过程,html是一种标记语言,它使用标记来描述文档结构和语义,并定义了网页中的各种元素和内容的呈现方式。本专题为大家提供html网页制作的相关的文章、下载、课程内容,供大家免费下载体验。

2023.07.31

3430

5

html空格
html空格

html空格是一种用于在网页中添加间隔和对齐文本的特殊字符,被用于在网页中插入额外的空间,以改变元素之间的排列和对齐方式。本专题为大家提供html空格的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.01

3459

5

html是什么
html是什么

HTML是一种标准标记语言,用于创建和呈现网页的结构和内容,是互联网发展的基石,为网页开发提供了丰富的功能和灵活性。本专题为大家提供html相关的各种文章、以及下载和课程。

2023.08.11

5059

6

html字体大小怎么设置
html字体大小怎么设置

在网页设计中,字体大小的选择是至关重要的。合理的字体大小不仅可以提升网页的可读性,还能够影响用户对网页整体布局的感知。php中文网将介绍一些常用的方法和技巧,帮助您在HTML中设置合适的字体大小。

2023.08.11

3401

3

html转txt
html转txt

html转txt的方法有使用文本编辑器、使用在线转换工具和使用Python编程。本专题为大家提供html转txt相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.31

3209

3

html文本框代码怎么写
html文本框代码怎么写

html文本框代码:1、单行文本框【<input type="text" style="height:..;width:..;" />】;2、多行文本框【textarea style=";height:;"></textare】。

2023.09.01

2788

6

HTML嵌入CSS样式的方法
HTML嵌入CSS样式的方法

HTML嵌入CSS样式的方法有内联样式、内部样式表和外部样式表。本专题为大家提供CSS样式相关的文章、下载、课程内容,供大家免费下载体验。

2023.09.20

2908

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
热门推荐
/
最新课程
phpStudy极速入门视频教程
phpStudy极速入门视频教程

共6课时 | 54.7万人学习

独孤九贱(4)_PHP视频教程
独孤九贱(4)_PHP视频教程

共89课时 | 134.1万人学习