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

使用jQuery UI Sortable编程设置每个棋子的对应位置

解决jQuery UI Sortable网格棋子编程式定位问题

要实现页面刷新后保留棋子位置、多用户同步看到位置的需求,核心是从数据库读取每个棋子的坐标,然后在网格渲染完成后将棋子放到对应单元格。以下是修改后的完整实现:

关键修改说明

  1. 角色数据扩展:从数据库拉取角色时需包含coords字段(格式如"0,1",空值表示角色在待选区)
  2. 定位函数:新增setCharacterPositions,根据坐标计算目标单元格并移动棋子
  3. 初始化时机:页面加载完成后自动执行位置初始化
  4. 多用户同步:新增可选的refreshCharacterPositions,用于拉取最新位置实现同步(可配合轮询或WebSocket)

修改后的代码

JavaScript

let gridSize = 7,
// 实际场景从数据库获取,包含coords字段
characters = [ {"id" : "1" , "name" : "测试角色", "hp" : "112", "coords": "2,3"} ];

// 生成网格
$('.grid')
  .css(`grid-template-columns`, `repeat(${gridSize}, 4rem)`)
  .html([...Array(gridSize**2)].map(() => '<div class="cell"></div>').join(''));

// 渲染角色容器
const $charactersContainer = $('.characters')
  .html(characters.map(character =>
    `<div class="character" data-character-id="${character.id}">
      <div class="stats" id='${character.id}'>
        <p>${character.name}</p>
        <p>hp: ${character.hp}</p>
      </div>
    </div>`).join(''));

// 初始化Sortable
$charactersContainer.add('.grid .cell').sortable({
  connectWith: '.characters, .grid .cell',
  cursor: 'grabbing',
  receive: (e, ui) => {
    if(ui.item.parent().hasClass('cell')) {
      const $cell = $(e.target);
      const coords = [
        $cell.index() % gridSize,
        Math.floor($cell.index() / gridSize)
      ].toString();
      const characterId = ui.item.find('.stats').attr('id');
      updateCharacterPosition(characterId, coords);
    }
  }
});

// 编程式设置角色位置
function setCharacterPositions() {
  characters.forEach(character => {
    if (!character.coords) return;
    const [x, y] = character.coords.split(',').map(Number);
    const cellIndex = y * gridSize + x;
    const $targetCell = $('.grid .cell').eq(cellIndex);
    const $character = $(`.character[data-character-id="${character.id}"]`);
    $targetCell.append($character);
  });
}

// 页面加载后初始化位置
$(document).ready(setCharacterPositions);

// 更新角色位置到数据库
function updateCharacterPosition(characterId, coords) {
  $.ajax({
    url: "/coords/" + characterId,
    method: 'PATCH',
    data: {
      _token: $('meta[name="csrf-token"]').attr('content'),
      newcoords: coords
    },
    success: () => {
      console.log('角色位置更新成功');
      // 可选:触发全局刷新同步给其他用户
      // refreshCharacterPositions();
    },
    error: (xhr, status, error) => {
      console.error('位置更新失败:', error);
    }
  });
}

// 可选:拉取所有角色最新位置(用于多用户同步)
function refreshCharacterPositions() {
  $.get('/coords/all', data => {
    characters = data;
    $charactersContainer.html(characters.map(character =>
      `<div class="character" data-character-id="${character.id}">
        <div class="stats" id='${character.id}'>
          <p>${character.name}</p>
          <p>hp: ${character.hp}</p>
        </div>
      </div>`).join(''));
    setCharacterPositions();
  });
}

CSS

.grid{
  border: 2px solid gray;
  display: grid;
  width: fit-content;
}

.grid .cell{
  align-items: center;
  aspect-ratio: 1 / 1;
  border: 1px solid lightgray;
  display: flex;
  justify-content: center;
  overflow: visible;
}

.grid .cell:has(.character):hover{
  border-width: 2px;
  box-sizing: border-box;
}

.characters{
  border: 2px solid gray;
  display: flex;
  gap: 1rem;
  margin-top: 1rem;
  min-height: 3rem;
  min-width: 6rem;
  padding: 1rem;
  width: fit-content;
}

.character{
  align-items: end;
  background-color: #000000;
  border-radius: 50%;
  color: #ffffff;
  display: flex;
  height: 3rem;
  justify-content: center;
  text-align: center;
  width: 3rem;
  cursor: grab;
}

.character .stats{
  background-color: inherit;
  padding: 4px;
}

.character p{
  font-size: .66rem;
  margin: 0;
  white-space: nowrap;
}

HTML

<div class="grid"></div>
<div class="characters"></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
<meta name="csrf-token" content="{{ csrf_token() }}">

后端配合要点

  1. 角色数据接口:GET /coords/all 返回包含id、name、hp、coords的角色列表
  2. 更新接口:PATCH /coords/{id} 接收newcoords参数并更新数据库
  3. 实时同步优化:如果需要低延迟的多用户同步,推荐用Laravel Echo + WebSocket(如Pusher),当位置更新时推送给所有在线用户,触发refreshCharacterPositions

内容的提问来源于stack exchange,提问作者Scarlet D.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 04:45:05