Откат Jquery UI Droppable не может снова упасть

Я пытался создать систему перетаскивания для приложения для изучения слов и столкнулся с проблемой, связанной с невозможностью повторного использования перетаскиваемых элементов после того, как я верну их и попытаюсь перетащить их снова.

Чтобы вернуть перетаскиваемый объект, я использовал метод out, поэтому, когда вы перетаскиваете его обратно из перетаскиваемой области, он возвращается в свое предыдущее местоположение. Я сделал это, удалив перетаскиваемый экземпляр и добавив его обратно, если я попытаюсь перетащить тот же элемент обратно в область перетаскивания, он не сможет его удалить. Я также пробовал повторно инициализировать удаляемую область, но, похоже, это ничего не меняет.

$(document).ready(function () {
  createDraggable();
  createDroppable();
});

function createDraggable(){
  $(".word").draggable({
    containment: ".stage",
    revert: 'invalid',
    revertDuration: 0
  });
}

function disableOtherDraggable(except){
  $(".word:not(#" + except.attr('id') + ")").draggable('disable');
}

function createDroppable(){
  $('.drop').droppable({
    tolerance: 'touch',
    accept: '.word',
    drop: function(event, ui) {
      ui.draggable.position({
        my: "center",
        at: "center",
        of: $(this),
        using: function(pos) {
          $(this).animate(pos, 200, "linear");
        }
      });
      $(ui.draggable).css('background', "transparent");
      disableOtherDraggable(ui.draggable);
    },
    out: function(event, ui) {
      ui.draggable.mouseup(function () {
        ui.draggable.removeAttr('style');
        $(".word").draggable("destroy");
        createDraggable();
      });
    }
  });
}

Я хочу, чтобы люди могли отбрасывать слова и перетаскивать их обратно, если это необходимо. Я собираюсь настроить кнопку, чтобы проверить правильность пропущенного слова после того, как я заработаю.

В этом примере можно перетащить 4 слова, но их может быть от 3 до 5.

Обновить

Вот обновленный код, который я получил для всех, кто заинтересован. Я создал сцену как выпадающую область и просто включал и выключал ее по мере необходимости.

$(function() {
  function createDraggable(o) {
    o.draggable({
      containment: ".stage",
      revert: 'invalid',
      revertDuration: 0
    });
  }

  function toggleOtherDraggable() {
    $(".words .word").each(function(i, val){
     if(!$(val).hasClass('ui-dropped')) $(val).draggable('disable');
    });
  }

  function createLineDroppable(){
    $('.drop').droppable({
      tolerance: 'touch',
      accept: '.word',
      drop: function(event, ui) {
        ui.draggable.position({
          my: "center",
          at: "center",
          of: $(this),
          using: function(pos) {
            $(this).animate(pos, 200, "linear");
          }
        });
        $(ui.draggable).css('background', 'transparent');
        $(ui.draggable).addClass('ui-dropped');
        toggleOtherDraggable();
      },
      out: function(){
        $('#stage-drop').droppable('enable');
      }
    });
  }

  function createStageDroppable() {
    $('#stage-drop').droppable({
      tolerance: 'touch',
      accept: '.word',
      disabled: true,
      drop: function(event, ui) {
        $(ui.draggable).css('left', '0');
        $(ui.draggable).css('top', '0');
        $(ui.draggable).css('background', '');
        $(ui.draggable).removeClass('ui-dropped');
        $('#stage-drop').droppable('disable');
        $(".words .word").draggable('enable');
      }
    });
  }

  createDraggable($(".words .word"));
  createLineDroppable();
  createStageDroppable();
});

person jasonCU    schedule 04.11.2019    source источник
comment
Я чувствую, что это может иметь какое-то отношение к revert: 'invalid'. Возможно, это слово будет рассматриваться как недопустимое, когда я попытаюсь отбросить его во второй раз, просто не зная, почему класс не изменился, поэтому он все равно должен его принять.   -  person jasonCU    schedule 04.11.2019
comment
Вы можете также показать свой HTML-код?   -  person Kamlesh Bhurke    schedule 04.11.2019
comment
Добро пожаловать в Stack Overflow. Я не вижу, где добавленный элемент добавляется к новому пространству. Я подозреваю, что ваша функция отключения слишком жадная и отключает слишком много, поскольку выпавший предмет находится не там, где должен быть.   -  person Twisty    schedule 04.11.2019


Ответы (1)


Вам нужно место для сброса .word, место, где вы хотите отключить остальные, и место, куда можно вернуться.

Рассмотрим следующий пример:

$(function() {
  function createDraggable(o) {
    o.draggable({
      containment: ".stage"
    });
  }

  function toggleOtherDraggable() {
    if ($(".words .word").eq(0).hasClass("ui-draggable-disabled")) {
      $(".words .word").draggable('enable');
    } else {
      $(".words .word").draggable('disable');
    }
  }

  function createDropWord() {
    $(".words").droppable({
      tolerance: 'touch',
      accept: '.word',
      drop: function(event, ui) {
        var item = ui.draggable;
        item.removeAttr("style");
        $(this).append(item);
      }
    });
  }

  function createDropStage() {
    $('.drop').droppable({
      tolerance: 'touch',
      accept: '.word',
      drop: function(event, ui) {
        var item = ui.draggable;
        item.appendTo(this).position({
          my: "center",
          at: "center",
          of: $(this),
          using: function(pos) {
            $(this).animate(pos, 200, "linear");
          }
        }).css('background', "transparent");
        toggleOtherDraggable();
        createDropWord()
      },
      out: function() {
        toggleOtherDraggable();
      }
    });
  }

  createDraggable($(".words > .word"));
  createDropStage();
});
.word {
  display: inline-block;
  padding: .25em;
}

.drop {
  width: 340px;
  height: 100px;
  background: #CCC;
  margin: 20px;
}

.word.ui-draggable-disabled {
  opacity: 0.45;
}
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<div class="stage">
  <div class="ui-widget words">
    <div id="word-1" class="word ui-widget-content">Word 1</div>
    <div id="word-2" class="word ui-widget-content">Word 2</div>
    <div id="word-3" class="word ui-widget-content">Word 3</div>
    <div id="word-4" class="word ui-widget-content">Word 4</div>
  </div>
  <div class="drop"></div>
</div>

Когда вы впервые перетаскиваете объект в область .drop, он центрирует перетаскиваемый объект, а также отключает другие перетаскиваемые элементы, поэтому их нельзя перетаскивать. Когда элемент перетаскивается, они снова включаются.

Вы должны использовать .append() или .appendTo(), чтобы выпадающий элемент затем добавлялся в контейнер. Это относится к обоим элементам.

Параметр revert включается только при определенных обстоятельствах падения. Если droppable не примет предмет или вернет false, то предмет будет возвращен, когда предпочтение будет отдано invalid.

person Twisty    schedule 04.11.2019
comment
Я использовал идею о том, что сцену можно сбрасывать, чтобы вернуть слово на исходное место. Я не добавлял при перемещении капли, потому что это заставляло мой дом странно прыгать. Я добавил обновленный код в свой вопрос для всех, кто ищет информацию. - person jasonCU; 06.11.2019