jquery 中的拖放功能将元素放置在看似随机的位置

问题描述 投票:0回答:1

我的代码出现了一些问题,但我根本无法指出在这种情况下会出现什么问题,我迷失了。

所以情况如下,我正在使用jquery制作一个简单的拖放界面,它所做的就是:制作一个网格,根据同一页面中的某个表格添加/删除“pawn”,然后拖放您想要的任何pawn想要在任何你想要的地方。一切都按预期进行,但几乎总是当我尝试将棋子放到一个正方形上时,它会传送到随机位置,很少会落在预期的位置。我不确定它是否相关,但我正在使用 laravel 10,这是一个刀片文件,我可以尝试什么建议吗?

<div class="col-md-3 gridframe">
            <h3 class="text-center">Character Grid</h3>
            <div id="grid" class="row mx-auto">
            </div>
        </div>

<style>
    .gridframe {
        width: 300px;
        border: 1px solid black;
        overflow: hidden; 
    }

    .grid-cell {
        width: 50px;
        height: 50px;
        border: 1px solid black;
        text-align: center;
        position: relative;
        float: left;
    }

    .character {
        width: 30px;
        height: 30px;
        background-color: black;
        color: white;
        border-radius: 50%;
        display: flex;
        justify-content: center;
        align-items: center;
        z-index: 999;
        position: absolute;
        top: 10px;
        left: 10px;
    }

</style>

</style>
<script src="https://ajax.googleapis.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>
<script>
   function insertCharacter(nickname, hp) {
        var cells = $('.grid-cell');
        cells.each(function() {
            if (!$(this).children('.character').length) {
                var row = $(this).data('row');
                var col = $(this).data('col');
                $(this).append('<div class="character" data-hp="' + hp + '">' + nickname + '<br>' + hp + '</div>');
                return false; 
            }
        });

        // make characters draggable 
        $('.character').draggable({
            revert: 'invalid',
            zIndex: 100,
            start: function(event, ui) {
                $(this).css('cursor', 'pointer');
            },
            stop: function(event, ui) {
                $(this).css('cursor', 'auto');
            }
        });

        // make grid cells droppable
        $('.grid-cell').droppable({
            accept: '.character',
            drop: function(event, ui) {
                var character = ui.draggable;
                // var characterHP = character.data('hp');
                character.appendTo($(this)); 
            }
        });
    }

    $(document).ready(function() {
        $('#character-table tbody').on('DOMNodeInserted', 'tr', function() {
            var nickname = $(this).find('td:eq(0)').text();
            var hp = $(this).find('td:eq(1)').text();
            insertCharacter(nickname, hp);
        });

        $('#character-table tbody').on('DOMNodeRemoved', 'tr', function() {
            var nickname = $(this).find('td:eq(0)').text();
            $('.character').each(function() {
                if ($(this).text().includes(nickname)) {
                    $(this).remove();
                }
            });
        });

        var gridSize = 10; 
        var grid = $('#grid');
        for (var i = 0; i < gridSize; i++) {
            for (var j = 0; j < gridSize; j++) {
                $('<div class="grid-cell" data-row="' + i + '" data-col="' + j + '"></div>').appendTo(grid);
            }
        }
    });
    </script>```
javascript jquery drag-and-drop
1个回答
0
投票

根据我的经验,让

draggable
droppable
一起工作也有你提到的同样的不一致之处。除非需要,我建议尝试使用 sortable 来代替。可排序功能与draggable + droppable非常相似,允许您使用
connectWith
属性链接多个容器。

这是一个简单的例子:

let gridSize = 5,
    characters = [
      { name: 'Frodo', hp: 100, type: 'hobbit' },
      { name: 'Data', hp: 105, type: 'android' },
      { name: 'Spiderman', hp: 62, type: 'human' }
    ];

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

$('.characters')
  .html(characters.map((character) =>
    `<div class="character"><div class="stats"><p>${character.name}</p><p>hp: ${character.hp}</p></div></div>`).join(``))
  .add('.grid .cell')
  .sortable({
    connectWith: '.characters, .grid .cell',
    cursor: 'grabbing',
    receive: (e, ui) => {
      if(ui.item.parent().hasClass('cell')) {
        let $cell = $(e.target),
            $character = ui.item,
            $characters = $cell.find('.character').not($character),
            coords = [$cell.index() % gridSize, Math.floor($cell.index() / gridSize)];
        //do stuff
      }
    }
  });
.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;}
  
.character .stats{
  background-color: inherit;
  padding: 4px;}

.character p{
  font-size: .66rem;
  margin: 0;
  white-space: nowrap;}
<div class="grid"></div>
<div class="characters"></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>

© www.soinside.com 2019 - 2024. All rights reserved.