jqueryUI 可拖动的 droppable 和数组中的项目问题

Posted

技术标签:

【中文标题】jqueryUI 可拖动的 droppable 和数组中的项目问题【英文标题】:jqueryUI draggable droppable and item from array problem 【发布时间】:2021-05-26 01:45:48 【问题描述】:

我有以下问题:

当我拿一张卡片并放入时,我第一次在索引中找到并放入正确的,但第二次我将其放入正确,但随后都按照最后一个进行等等。

这里的代码对我有用,它可能在这里不起作用:

$(document).ready(function() 
  $("body").append("<div id='top' </div>");
  $("#top").append("<h1> <b>BLACK JACK</b> </h1>");
  $("body").append("<div id='buttons' </div>");
  $("body").append("<div id='index'> </div>");
  $("body").append("<div id='gameDesk' </div>");
  $("body").append("<div id='cardsDesk' </div>");
  $("#buttons").append(
    "<button type='button'  id='startGame' class='btn btn-secondary'>Start game</button>"
  );

  const SuitValue = [
    (suit = ["S", "C", "D", "H"]),
    (value = [
      "2",
      "3",
      "4",
      "5",
      "6",
      "7",
      "8",
      "9",
      "10",
      "10J",
      "10Q",
      "10K",
      "11A",
    ]),
  ];

  var cardsArray = [];
  var shuffleCards = [];
  var playerCards = [];

  for (let i = 0; i < value.length; i++) 
    for (let j = 0; j < suit.length; j++) 
      cardsArray.push(value[i] + suit[j]);
    
  

  function shuffle(array) 
    var currentIndex = array.length,
      temporaryValue,
      randomIndex;

    // While there remain elements to shuffle...
    while (0 !== currentIndex) 
      // Pick a remaining element...
      randomIndex = Math.floor(Math.random() * currentIndex);
      currentIndex -= 1;

      // And swap it with the current element.
      temporaryValue = array[currentIndex];
      array[currentIndex] = array[randomIndex];
      array[randomIndex] = temporaryValue;
    

    return array;
  
  $("#startGame").click(function() 
    $("#buttons").html(
      "<button type='button'  id='shuffleCards' class='btn btn-secondary'>mix cards</button>"
    );
    $("#index").html(
      "<h5>" + "on the table " + cardsArray.length + " cards" + "</h4>"
    );
    for (let i = 0; i < cardsArray.length; i++) 
      var cards = cardsArray[i];
      $("#cardsDesk").append(`<img  src="assets/img/cards/$cards.png" />`);
    

    $("#shuffleCards").click(function() 
      $("#cardsDesk").remove();
      $("body").append("<div id='cardsDesk' </div>");

      shuffle(cardsArray);
      for (let i = 0; i < cardsArray.length; i++) 
        const element = cardsArray[i];
        $("#cardsDesk").append(
          `<img  src="assets/img/cards/card back black.png" />`
        );
      
      console.log(cardsArray);

      $("#buttons").html(
        "<button type='button'  id='enough' class='btn btn-secondary'>Enough</button>"
      );

      $("#gameDesk").append("<span  class='slot' >drag card here</span>");

      dragDrop();

      function dragDrop() 
        $("img").draggable(
          cursor: "grab",
          revert: true,
          snap: ".slot",
          snapMode: "center",
          snapTolerance: "",
          stack: "img",
        );

        $(".slot").droppable(
          accept: "img",
          activeClass: "ui-state-default",
          hoverClass: "ui-state-hover",

          drop: function(event, ui) 
            $(".slot").droppable("option", "disabled", true);
            $("img").draggable("option", "destroy", true);
            $(this).find("img").html();

            $(ui.draggable).remove();
            var imgIndex = $(this).index();
            var src = cardsArray[imgIndex];
            $(".slot").html(
              `<img class="playerCard"  src="assets/img/cards/$src.png" />`
            );
            $(".playerCard").draggable(
              disabled: true,
            );
            $("<span  class='slot' >drag card here</span>")
              .droppable()
              .appendTo("#gameDesk");

            console.log(src);
            return dragDrop();
          ,
        );
      
      $("#enough").click(function() );
    );
  );
);
html 
  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);


body 
  background-color: darkgreen;


#top 
  display: flex;
  justify-content: center;
  background-color: darkgreen;
  text-align: center;


h1 
  font-family: Georgia, "Times New Roman", Times, serif;


#buttons 
  display: flex;
  justify-content: center;
  background-color: darkgreen;
  text-align: center;


#index 
  background-color: darkgreen;
  text-align: center;


#gameDesk 
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  padding-left: 50px;
  padding-bottom: 20px;
  background-color: darkgreen;


.slot 
  margin-right: 40px;
  margin-bottom: 20px;
  background-color: rgb(11, 126, 11);
  border-radius: 2px;
  text-align: center;
  font-size: 1rem;
  font-weight: bold;
  width: 3rem;


#cardsDesk 
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: flex-start;
  background-color: darkgreen;
  max-height: 39rem;


img 
  height: 7.3rem;
  width: 5rem;


.imgDrag 
  z-index: 1;
  opacity: 0.5;
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<body>

</body>

https://jsfiddle.net/Lfd07y8e/

【问题讨论】:

您知道您正试图在此处附加无效的 HTML 吗? 【参考方案1】:

不是 100% 确定你在尝试什么,但我在这里创建了一些“玩家插槽”并让你将卡片拖到其中。

我发现了所有语法问题,并将 HTML 从脚本中移到标记中,创建了一个“槽”,我可以克隆它来放入卡片。

我还为此设置了一些命名空间,希望可以更轻松地在此处隔离您的关注点(要调用的对象和函数等)

/* this is bad, moved to the HTML */
/*
  $("body").append("<div id='top"> </div>");
  $("#top").append("<h1> <b>BLACK JACK</b> </h1>");
  $("body").append("<div id='buttons'> </div>");
  $("body").append("<div id='index'> </div>");
  $("body").append("<div id='gameDesk'> </div>");
  $("body").append("<div id='cardsDesk'> </div>");
  
  $("#buttons").append(
    "<button type='button'  id='startGame' class='btn btn-secondary'>Start game</button>"
  );*/

// simple namespace all this and create descrete functions and values
var myGame = 
  SuitValue: 
    suit: ["S", "C", "D", "H"],
    value: ["2", "3", "4", "5", "6", "7", "8", "9", "10", "10J", "10Q", "10K", "11A"]
  ,
  cardsArray: [],
  shuffleCards: [],
  playerCards: [],
  numberOfPlayers: 3,
  setup: function() 
    for (let i = 0; i < this.SuitValue.value.length; i++) 
      for (let j = 0; j < this.SuitValue.suit.length; j++) 
        this.cardsArray.push(this.SuitValue.value[i] + this.SuitValue.suit[j]);
      
    
  ,
  shuffle: function(cards) 
    let currentIndex = cards.length,
      temporaryValue,
      randomIndex;
    // While there remain elements to shuffle...
    while (!!currentIndex) 
      // Pick a remaining element...
      randomIndex = Math.floor(Math.random() * currentIndex);
      currentIndex -= 1;
      // And swap it with the current element.
      temporaryValue = cards[currentIndex];
      cards[currentIndex] = cards[randomIndex];
      cards[randomIndex] = temporaryValue;
    
    return cards;
  ,
  placeCard: function(card) 
    $("#cardsDesk").append(`<img class="this-card" src="assets/img/cards/$card.png"  />`);
  ,
  startGame: function(event) 
    $("#shuffleCards").show();
    $("#index").html("<h5> on the table " + myGame.cardsArray.length + " cards</h4>");
    for (let i = 0; i < myGame.cardsArray.length; i++) 
      let card = myGame.cardsArray[i];
      myGame.placeCard(card);
    
  ,
  shuffleHandler: function(event) 
    // console.log("shuffle handle");
    let cardsDeck = $("#cardsDesk");
    let game = $("#gameDesk");
    cardsDeck.hide().empty();
    let cards = myGame.shuffle(myGame.cardsArray);
    for (let i = 0; i < cards.length; i++) 
      let card = cards[i];
      myGame.placeCard(card);
      // cardsDeck.append(`<img class="this-card" src="assets/img/cards/card back black.png"  />`);
    
    cardsDeck.show();
    //console.log(myGame.cardsArray);
    $("#enough").show();
    let h = $('#hold-stuff').find(".slot.hidden").first();
    for (let p = 0; p < myGame.numberOfPlayers; p++) 
      let s = h.clone();
      game.append(s);
    
    game.find(".slot.hidden").removeClass('hidden').addClass("player-slot");
    dragDrop();
  
;

$(function() 
  $("#startGame").on('click', myGame.startGame);
  $("#shuffleCards").on("click", myGame.shuffleHandler);
  myGame.setup();
);

function dragDrop() 
  $("#cardsDesk")
    .find("img.this-card")
    .draggable(
      cursor: "grab",
      revert: true,
      snap: ".slot",
      snapMode: "center",
      snapTolerance: "",
      stack: "img",
    );
  $('#gameDesk')
    .find(".player-slot")
    .droppable(
      accept: ".this-card",
      activeClass: "ui-state-default",
      tolerance: "pointer",
      hoverClass: "ui-state-hover",
      drop: function(event, ui) 
        ui.draggable.detach().appendTo($(this));
      
    );

$("#enough").on('click', function() 
  console.log("get out now");
);
.hidden 
  display: none;


html 
  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);


body 
  background-color: darkgreen;


#top 
  display: flex;
  justify-content: center;
  background-color: darkgreen;
  text-align: center;


h1 
  font-family: Georgia, "Times New Roman", Times, serif;


#buttons 
  display: flex;
  justify-content: center;
  background-color: darkgreen;
  text-align: center;


#index 
  background-color: darkgreen;
  text-align: center;


#gameDesk 
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  padding-left: 50px;
  padding-bottom: 20px;
  background-color: darkgreen;


.slot 
  margin-right: 40px;
  margin-bottom: 20px;
  background-color: 0b7e0b;
  border-radius: 2px;
  text-align: center;
  font-size: 1rem;
  font-weight: bold;
  width: 3rem;


#cardsDesk 
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: flex-start;
  background-color: darkgreen;
  max-height: 39rem;


img 
  height: 7.3rem;
  width: 5rem;


.imgDrag 
  z-index: 1;
  opacity: 0.5;
<link src="https://code.jquery.com/ui/1.11.4/themes/redmond/jquery-ui.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>

<div id='top'> </div>
<h1> <b>BLACK JACK</b> </h1>
<div id='buttons'>
  <button type='button' id='startGame' class='btn btn-secondary'>Start game</button>
  <button type='button' id='shuffleCards' class='btn btn-secondary hidden'>mix cards</button>
  <button type='button' id='enough' class='btn btn-secondary'>Enough</button>
</div>
<div id='index'></div>
<div id='gameDesk'></div>
<div id='cardsDesk'></div>
<div id="hold-stuff">
  <span class='slot hidden'>drag card here</span>
</div>

【讨论】:

非常感谢您的帮助,也许不是我需要的,但是(也许我自己问错了问题)..我提到好的答案在答案中,我将能够移动on..我还刚刚开始,所以每个更正提示都非常重要..再次非常感谢您 @DarŽuk 很高兴这对您有所帮助,其中有很多超出了问题的范围(脚本中的未封闭标签,如 &lt;div id='top' &lt;/div&gt; - 我更喜欢将元素/标签放在 HTML 中而不是脚本,因为在开发工具中更容易维护和注意到这一点。重现问题的最简单示例将在未来的问题中为您提供帮助。 对于 CSS,我经常使用“它可以工作,现在我可以删除什么仍然可以,但使它更简单或不那么常用”

以上是关于jqueryUI 可拖动的 droppable 和数组中的项目问题的主要内容,如果未能解决你的问题,请参考以下文章

jQuery UI (Droppable):如果 droppable 具有相对/绝对的 css 位置,则可拖动元素不会放置在鼠标指针处

jQuery/jQueryUI Droppable 采用 Draggable 的形式

jQuery UI - Droppable 只接受一个可拖动的

jQuery UI 的贪婪 droppable 无法按预期工作

JQueryUI droppable drop 事件在恢复之前触发

JQuery Droppable 不接受可拖动项目