HTML5 drag and drop - только для элемента в зоне - PullRequest
0 голосов
/ 30 октября 2018

У меня есть некоторые div-ы в виде dropzones, а некоторые в качестве перетаскиваемых объектов.

<div class="container">
   <div class="drop"></div>
   <div class="drop"></div>
   <div class="drop"></div>
</div>
<div class="container">
    <div class="drag" id="drag-a" draggable="true">box a</div>
    <div class="drag" id="drag-b" draggable="true">box b</div>
    <div class="drag" id="drag-c" draggable="true">box c</div>
</div>
<style>
.drop {
    border: 1px solid #000;
    height: 40px;
    margin: 5px;
    width: 200px;
}
.drag {
    background: #000;
    color: #fff;
    display: inline-block;
    margin: 5px;
    padding: 5px;
    user-select: none;
}
</style>
<script>
$(document).ready(function () {
    $('.drop').on('dragover', function(e){
        e.preventDefault();
    });
    $('.drag').on('dragstart', function(e) {
        e.originalEvent.dataTransfer.setData('Text', e.target.id);
    });
    $('.drop').on('drop', function(e) {
        e.preventDefault();
        var data = e.originalEvent.dataTransfer.getData('Text');  
        e.target.appendChild(document.getElementById(data));
    });
});
</script>

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

Возможно ли, что два перетаскиваемых блока меняются местами?

1 Ответ

0 голосов
/ 30 октября 2018

Вам просто нужно удалить обработчик событий для этого элемента, в jQuery вы можете сделать это с помощью `.off () .

$('.drop').on('drop', function(e) {
    e.preventDefault();
    var data = e.originalEvent.dataTransfer.getData('Text');  
    e.target.appendChild(document.getElementById(data));
    // add this line
    $(this).off('dragover drop');
});

$(document).ready(function () {
    $('.drop').on('dragover', function(e){
        e.preventDefault();
    });
    $('.drag').on('dragstart', function(e) {
        e.originalEvent.dataTransfer.setData('Text', e.target.id);
    });
    $('.drop').on('drop', function(e) {
        e.preventDefault();
        var data = e.originalEvent.dataTransfer.getData('Text');  
        e.target.appendChild(document.getElementById(data));
        $(this).off('dragover drop');
    });
});
.drop {
    border: 1px solid #000;
    height: 40px;
    margin: 5px;
    width: 200px;
}
.drag {
    background: #000;
    color: #fff;
    display: inline-block;
    margin: 5px;
    padding: 5px;
    user-select: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
   <div class="drop"></div>
   <div class="drop"></div>
   <div class="drop"></div>
</div>
<div class="container">
    <div class="drag" id="drag-a" draggable="true">box a</div>
    <div class="drag" id="drag-b" draggable="true">box b</div>
    <div class="drag" id="drag-c" draggable="true">box c</div>
</div>

Перезапуск функции перетаскивания мышью

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

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

Затем разрешите контейнеру коробки принимать операции перетаскивания.

Последнее, когда пользователь бросает ящик в контейнер, снова добавляет обработчики для событий drop и dragover в любую пустую зону сброса.

Примечание: на этот раз я немного изменил название классов, чтобы сделать его более понятным.

var dragOverHandler = function(e) {
  e.preventDefault();
};
var dropOnDropZoneHandler = function(e) {
  e.preventDefault();
  var data = e.originalEvent.dataTransfer.getData('Text');
  e.target.appendChild(document.getElementById(data));
  $(this).off('dragover drop');
};
var dropOnBoxContainerHandler = function(e) {
  e.preventDefault();
  var data = e.originalEvent.dataTransfer.getData('Text');
  e.target.appendChild(document.getElementById(data));
  $('.dropzone').each(function() {
    if ($(this).is(':empty')) {
      $(this).on('dragover', dragOverHandler);
      $(this).on('drop', dropOnDropZoneHandler);
    }
  });
}

$(document).ready(function() {
  $('.box').on('dragstart', function(e) {
    e.originalEvent.dataTransfer.setData('Text', e.target.id);
  });
  $('.dropzone, #boxContainer').on('dragover', dragOverHandler);
  $('.dropzone').on('drop', dropOnDropZoneHandler);
  $('#boxContainer').on('drop', dropOnBoxContainerHandler);
});
.dropzone, #boxContainer {
  border: 1px solid #000;
  height: 40px;
  margin: 5px;
  width: 200px;
}

.box {
  background: #000;
  color: #fff;
  display: inline-block;
  margin: 5px;
  padding: 5px;
  user-select: none;
}

#boxContainer {
  background-color: #AAA;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
  <div class="dropzone"></div>
  <div class="dropzone"></div>
  <div class="dropzone"></div>
</div>
<div id="boxContainer">
  <div class="box" id="drag-a" draggable="true">box a</div>
  <div class="box" id="drag-b" draggable="true">box b</div>
  <div class="box" id="drag-c" draggable="true">box c</div>
</div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...