javascript 如何找到一个grid item被拖动前后的index

How to find the index of a grid item before and after being dragged in javascript

我正在用 HTML、CSS 和 JS 制作国际象棋游戏,但我不知道如何在拖动前后获取网格中棋子的索引(我也使用jquery 和 jquery-ui)

这是“游戏”的图片:

https://i.stack.imgur.com/w3qmG.png

代码 HTML

<div class="chessboard ">
  <div class="cell white">
    <img class="piece" id="rook" draggable="true" src="assets/pieces/black/rook.png" alt="">
  </div>
  <div class="cell black">
    <img class="piece" id="knight" draggable="true" src="assets/pieces/black/knight.png" alt="">
  </div>

  ..............................................

  <div class="cell black">
    <img class="piece" id="knight" draggable="true" src="assets/pieces/white/knight.png" alt="">
  </div>
  <div class="cell white">
    <img class="piece" id="rook" draggable="true" src="assets/pieces/white/rook.png" alt="">
  </div>
</div>

代码 JS

const pieces = document.querySelectorAll(".piece");
const grid = document.querySelector(".chessboard");
var grid_layout = []

// i tried to find at least the starting position by clicking on the pieces
pieces.forEach((piece) => {
  piece.addEventListener("click", () => {
    console.log($(piece.id).index())
  })
})

这是我失败的尝试之一

function GetElementIndex() {
  if ($('.piece').hasClass("ui-draggable-dragging")) {
    console.log(GetGridElementsPosition($('.piece').index()));
  }
}

这个函数 returns 一个元素的位置,给定索引(我正在寻找),幸运的是这个函数很好用 quite well

function GetGridElementsPosition(index) {
  const colCount = $(".chessboard")
    .css("grid-template-columns")
    .split(" ").length;
  const rowPosition = Math.floor(index / colCount) + 1;
  const colPosition = (index % colCount) + 1;
  return { row: rowPosition, column: colPosition };
}

下面是可以拖动棋子的函数

$(function () {
  $(".piece").draggable({
    start: function () {
      console.log("Starting Index:");
      GetElementIndex();
    },
    stop: function () {
      console.log("Ending Index:");
      GetElementIndex();
    },
    grid: [100, 100],
    activeClass: "dragging",
  });
});

编辑

因此,由于评论的一些帮助,我设法得到了我需要的东西。我给网格的每个单元格一个 x 和 y 值(如 {1, 1} 或 {5, 8}),我通过 js 渲染这些片段而不是 html。然后我通过这样做找到了他们当前的位置:

var col = Math.ceil($(this).position().left / 100);
var row = Math.ceil($(this).position().top / 100);

这只是被拖动的部分(draggable() 中的内部函数)

最简单的方法可能是在 html 生成时向具有 data-xdata-y 作为自定义 html 属性的单元格添加一个位置? https://www.w3schools.com/tags/att_global_data.asp

这在很大程度上取决于您是如何实现棋盘的。 顺便说一句,你让我试着自己做一个:)

它只是棋子和移动棋子..他们不能攻击或正确移动(根据规则)。

Chessboard on codepen.io

const game = document.getElementById("game");
const squares = [];

const createSquare = (color, index) => {
    const el = document.createElement("div");
    el.classList.add(color, "square");
    el.dataset.index = index;
    el.dataset.color = color;
    game.appendChild(el);
    squares.push(el);

    document.addEventListener("click", movePiece);
};

let c = 0;
const createChessboard = () => {
    for (let i = 0; i < 8; i++) {
        for (let j = 0; j < 8; j++) {
            let color;
            if (i % 2) {
                color = j % 2 ? "white" : "black";
            } else {
                color = j % 2 ? "black" : "white";
            }
            createSquare(color, c);
            c++;
        }
    }
};
createChessboard();

const playerWhite = {
    side: "white",
    pieces: {
        rook1: { name: "Rook", side: "white", index: 0 },
        knight1: { name: "Knight", side: "white", index: 1 },
        bishop1: { name: "Bishop", side: "black", index: 2 },
        king: { name: "King", side: "white", index: 3 },
        queen: { name: "Queen", side: "white", index: 4 },
        bishop2: { name: "Bishop", side: "black", index: 5 },
        knight2: { name: "Knight", side: "white", index: 6 },
        rook2: { name: "Rook", side: "white", index: 7 },

        pawn1: { name: "Pawn", side: "white", index: 8 },
        pawn2: { name: "Pawn", side: "white", index: 9 },
        pawn3: { name: "Pawn", side: "white", index: 10 },
        pawn4: { name: "Pawn", side: "white", index: 11 },
        pawn5: { name: "Pawn", side: "white", index: 12 },
        pawn6: { name: "Pawn", side: "white", index: 13 },
        pawn7: { name: "Pawn", side: "white", index: 14 },
        pawn8: { name: "Pawn", side: "white", index: 15 }
    }
};

const playerBlack = {
    side: "black",
    pieces: {
        rook1: { name: "Rook", side: "black", index: 56 },
        knight1: { name: "Knight", side: "black", index: 57 },
        bishop1: { name: "Bishop", side: "black", index: 58 },
        king: { name: "King", side: "black", index: 60 },
        queen: { name: "Queen", side: "black", index: 59 },
        bishop2: { name: "Bishop", side: "black", index: 61 },
        knight2: { name: "Knight", side: "white", index: 62 },
        rook2: { name: "Rook", side: "black", index: 63 },

        pawn1: { name: "Pawn", side: "black", index: 48 },
        pawn2: { name: "Pawn", side: "black", index: 49 },
        pawn3: { name: "Pawn", side: "black", index: 50 },
        pawn4: { name: "Pawn", side: "black", index: 51 },
        pawn5: { name: "Pawn", side: "black", index: 52 },
        pawn6: { name: "Pawn", side: "black", index: 53 },
        pawn7: { name: "Pawn", side: "black", index: 54 },
        pawn8: { name: "Pawn", side: "black", index: 55 }
    }
};

const setPlayerFigures = (player) => {
    for (let piece in player.pieces) {
        const thePiece = player.pieces[piece];

        const el = document.createElement("div");
        el.classList.add(player.side, "piece");
        el.dataset.id = `${player.side}~${piece}`;

        const text = document.createElement("span");
        text.textContent = thePiece.name;
        el.appendChild(text);

        squares[thePiece.index].appendChild(el);
        thePiece.square = squares[thePiece.index];
    }
};

setPlayerFigures(playerWhite);
setPlayerFigures(playerBlack);

let selectedSquare = null;
function movePiece(e) {
    const selectedPiece = selectedSquare && selectedSquare.childNodes[0];
    const clickedPiece = e.target.childNodes[0];
    const clickedSquare = e.target;

    // console.log(selectedPiece)
    // console.log(clickedPiece);

    if (selectedPiece === clickedPiece) {
        clickedPiece.classList.remove("active");
        selectedSquare = null;
        return;
    }

    if (selectedPiece && clickedPiece) {
        // trying to move to another piece
        // there will be code for 'take' the piece

        //FOR NOW just select another piece
        selectedPiece.classList.remove("active");
        clickedPiece.classList.add("active");
        selectedSquare = clickedSquare;
        // TODO --> delete this
        return;
    }

    if (selectedSquare && !clickedPiece && selectedPiece) {
        selectedPiece.classList.remove("active");
        clickedSquare.appendChild(selectedPiece);
        selectedSquare = null;
        return;
    }

    selectedSquare = clickedSquare;
    clickedPiece && clickedPiece.classList.add("active");
}
#game {
    border: 2px double gray;
    display: flex;
    flex-wrap: wrap;
    width: 400px;
}

.square {
    width: 46px;
    height: 46px;
    display: flex;
    justify-content: center;
    align-items: center;
    transition: border 0.1s;

    cursor: pointer;
}

.square.white {
    background: #ccc;
    border: 2px solid #ccc;
}
.square.white:hover {
    border: 2px solid #888;
}

.square.black {
    background: #444;
    border: 2px solid #444;
}
.square.black:hover {
    border: 2px solid #888;
}

.piece {
    pointer-events: none;
    border-radius: 50%;
    width: 35px;
    height: 35px;
    display: flex;
    justify-content: center;
    align-items: center;
    font-size: 0.7rem;
}

.piece.white {
    background: #fff;
    border: 2px solid black;
    color: black;
}
.piece.black {
    background: #000;
    border: 2px solid white;
    color: white;
}

.piece.active {
    border-color: #20e320;
}
<div id="game"></div>