jQuery UI 可拖放项目

Posted

技术标签:

【中文标题】jQuery UI 可拖放项目【英文标题】:jQuery UI Droppable items 【发布时间】:2021-11-11 15:19:31 【问题描述】:

你好 我有个问题。问题是,当我将一个项目移动到多个插槽时,它可以完美运行。 但是,当我有两个相同类型的项目时,我将它们放在一起时,它会变成一个值为 2 的项目。 但我不知道如何将这两个项目分成两个单独的项目,其值为 1。

                if($(this)[0].querySelector('.size').innerText > 1) 
                $(this).children().children().html(1);
            

项目:https://codepen.io/KsenonAdv/pen/bGRaRjR

【问题讨论】:

欢迎来到 Stack Overflow。最好参加游览:***.com/tour 您可能还想编辑您的帖子并将相关代码移动到您的帖子,而不仅仅是链接到 CodePen。 您将需要在拖动开始或放下项目时检查计数并调整两个项目的计数。 @Twisty 但是如何替换下一个框中的 div? 有很多方法可以实现这一点。在 Drag Start 中,您可以检查 Count 是否大于 1 并克隆要拖放的拖动项。 @Twisty 一个例子? 【参考方案1】:

考虑以下示例。

$(function() 
  function log(string) 
    console.log(Date.now(), string);
  

  function makeGrid() 
    log("Make Grid...");
    for (var i = 0; i < 36; i++) 
      $("<div>", 
        class: "slot"
      ).data(
        count: 0,
        stackable: true
      ).appendTo(".slots");
    
    log("-* Grid Complete *-");
  

  function makeDraggable(target) 
    log("Make Drag, Current Class: " + $(target).attr("class"));
    console.log(target);
    $(target).draggable(
      scroll: false,
      helper: "clone",
      cursor: "pointer",
      zIndex: 27,
      revert: "invalid"
    );
    log("After Make Drag, Current Class: " + $(target).attr("class"));
    console.log(target);
  

  function refreshSlot(target) 
    log("Refresh Slot");
    $(".size", target).html($(target).data("count"));
  

  function addItem(slot, item) 
    log("Add Item " + item.id);
    $.extend(item, 
      stackable: (item.category != 0),
      count: (item.count == undefined ? 1 : item.count)
    );
    slot = $(slot);
    var newItem = $("<div>", 
        class: "item",
        id: item.id,
      )
      .data(item)
      .css("background-image", "url(" + item.img + ")");
    newItem.appendTo(slot);
    $("<div>", 
      class: "size"
    ).appendTo(slot);
    slot.data(
      count: item.count,
      stackable: item.stackable
    );
    log("Item Added - Refreshing");
    refreshSlot(slot);
  

  function emptySlot(target) 
    log("Empty Slot " + $(target).index());
    $(target).data(
      count: 0,
      stackable: true
    ).empty();
  

  function loadPlayerItems(items) 
    log("Loading Player Items...");
    $.each(items, function(index, item) 
      addItem($(".slots > .slot").eq(index), item);
    );
    log("-* Loading Complete *-");
  

  function isAcceptable(item) 
    if ($(this).children().length == 0 || $(".item", this).data("stackable")) 
      return true;
    
    return false;
  

  var pItems = 
    playerItems: [
        img: 'https://i.imgur.com/5cjSI9X.png',
        name: 'bat',
        id: 1,
        category: 0
      ,
      
        img: 'https://i.imgur.com/HLQORBk.png',
        name: 'axe',
        id: 2,
        category: 1
      ,
      
        img: 'https://i.imgur.com/HLQORBk.png',
        name: 'axe',
        id: 3,
        category: 1
      
    ]
  ;

  makeGrid();
  loadPlayerItems(pItems.playerItems);
  makeDraggable(".item");

  $(".slots > .slot").droppable(
    accept: isAcceptable,
    drop: function(event, ui) 
      var origin = ui.draggable.parent();
      var target = $(this);
      log("Drop Accepted; From: " + origin.index() + ", To: " + target.index());
      // Increase the Count
      target.data("count", target.data("count") + 1);
      // Check for Stack
      if (target.children().length == 0) 
        addItem(target, ui.draggable.data());
       else 
        refreshSlot(target);
      
      // Check Orginal Stack
      if (origin.data("count") > 1) 
        origin.data("count", origin.data("count") - 1);
        refreshSlot(origin);
       else 
        emptySlot(origin);
      
      makeDraggable($(".item", this));
    
  );
);
body 
  display: flex;
  justify-content: space-between;
  background: url(http://img.playground.ru/images/5/1/GTA5_2015-05-07_00-53-36-07.png);


#inventory 
  height: 56.25vw;
  background: rgba(0, 0, 0, .5);


.list-slots 
  position: relative;
  background: rgba(0, 0, 0, .7);
  max-width: 80%;


.slots 
  max-width: 87%;
  margin: auto;
  padding-top: 3.125vw;
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;


.slots .slot 
  width: 100px;
  height: calc(100px + 1em);
  background-color: #ccc;
  margin-bottom: 0.781vw;


.slots .slot .item 
  background-repeat: no-repeat;
  width: 100px;
  height: 100px;
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-3.5.1.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<div id="inventory">
  <div class="list-slots">
    <div class="slots"></div>
  </div>
</div>

正如评论中所讨论的,这会将 Slot 中的项目计数更新为 1。当一个项目被拖出时,计数会降低 1。

为了让事情变得更简单,我创建了许多函数。如果您愿意,可以选择以其他方式处理。

【讨论】:

以上是关于jQuery UI 可拖放项目的主要内容,如果未能解决你的问题,请参考以下文章

拖放后向可拖放项目添加标签

可拖放的 jquery socket.io

可排序、可拖放和可拖动的容器

使用 jQuery 在表格中拖放(使用两个可拖放的函数)

jQuery 可拖放定位

让 jQuery 可排序、可拖放和可拖动以协同工作