如何限制可拖动元素只能放置在预定义的 div 元素内?

7
我正在使用interact.js,希望能够在预定义的
内启用可拖动对象的放置功能,以便禁用在
外部的放置。我引入了restriction:".dropzone", drag:document.getElementById('dropzone'),但它无法正常工作。

我创建了this JFIDDLE以更清晰地说明问题(我更新了链接,因为旧链接不正确)。

JavaScript:

// target elements with the "draggable" class
interact('.draggable').draggable({
    inertia: true,
    restrict: {
      restriction: ".dropzone",
      drag: document.getElementById('dropzone'),
      endOnly: true,
      elementRect: {
        top: 0,
        left: 0,
        bottom: 1,
        right: 1
      }
    },
    autoScroll: true,
    onmove: function(event) {
      var target = event.target;
      var x = (parseFloat(target.getAttribute('data-x')) || 0) + event.dx;
      var y = (parseFloat(target.getAttribute('data-y')) || 0) + event.dy;

      target.style.transform = 'translate(' + x + 'px, ' + y + 'px)';

      target.setAttribute('data-x', x);
      target.setAttribute('data-y', y);
    },
    onend: function(event) {
      console.log(event);
    }
  })
  .on('move', function(event) {
    var interaction = event.interaction;
    if (interaction.pointerIsDown && !interaction.interacting() && event.currentTarget.getAttribute('clonable') != 'false') {
      var original = event.currentTarget;
      var clone = event.currentTarget.cloneNode(true);
      var x = clone.offsetLeft;
      var y = clone.offsetTop;
      clone.setAttribute('clonable', 'false');
      clone.style.position = "absolute";
      clone.style.left = original.offsetLeft + "px";
      clone.style.top = original.offsetTop + "px";
      original.parentElement.appendChild(clone);
      interaction.start({
        name: 'drag'
      }, event.interactable, clone);
    }
  })
  .resizable({
    edges: {
      left: true,
      right: true,
      bottom: true,
      top: true
    }
  })
  .on('resizemove', function(event) {
    var target = event.target;
    x = (parseFloat(target.getAttribute('data-x')) || 0),
      y = (parseFloat(target.getAttribute('data-y')) || 0);

    // update the element's style
    target.style.width = event.rect.width + 'px';
    target.style.height = event.rect.height + 'px';

    // translate when resizing from top or left edges
    x += event.deltaRect.left;
    y += event.deltaRect.top;

    target.style.webkitTransform = target.style.transform =
      'translate(' + x + 'px,' + y + 'px)';

    target.setAttribute('data-x', x);
    target.setAttribute('data-y', y);
    //target.textContent = event.rect.width + '×' + event.rect.height;
  });

// enable draggables to be dropped into this
interact('.dropzone').dropzone({
  // Require a 50% element overlap for a drop to be possible
  overlap: 0.50,

  // listen for drop related events:

  ondropactivate: function(event) {
    // add active dropzone feedback
    event.target.classList.add('drop-active');
  },
  ondragenter: function(event) {
    var draggableElement = event.relatedTarget,
      dropzoneElement = event.target;

    // feedback the possibility of a drop
    dropzoneElement.classList.add('drop-target');
  },
  ondragleave: function(event) {
    // remove the drop feedback style
    event.target.classList.remove('drop-target');
  },
  ondrop: function(event) {
    //event.relatedTarget.textContent = 'Dropped';
  },
  ondropdeactivate: function(event) {
    // remove active dropzone feedback
    event.target.classList.remove('drop-active');
    event.target.classList.remove('drop-target');
  }
});

$(".dropzone").html("<img src='https://s-media-cache-ak0.pinimg.com/originals/fb/d5/55/fbd5556e0e364b31166bebfce433c14e.jpg'>");


function popupBaseDetails(div, e) {
  e.preventDefault();
  div.querySelector(".basepopup").classList.toggle("show");
}

CSS:

.dropzone {
  background-color: #e9ebed;
  padding: 10px;
  width: 100%;
  height: 600px;
  overflow-y: scroll;
  border: dashed 4px transparent;
  float: left;
}

.drop-active {
  border-color: #aaa;
}

.drop-target {
  background-color: #3f5265;
  color: #FFF;
  border-color: #fff;
  border-style: solid;
}

HTML:

<div style="height:280px">
  <div id="dropzone" class="dropzone"></div>
</div>

我知道这是一个老问题,但你解决了吗? - Abdullah Abid
2个回答

0

使用这个而不是这个限制:document.getElementById('dropzone')

restriction: '.dropzone',

0

您可以使用限制修饰符将可拖动元素限制在放置区域中:

interact('.draggable').draggable({
    inertia: true,
    modifiers: [
      interact.modifiers.restrictRect({
        restriction: document.getElementById('dropzone'),
        endOnly: true
      })
    ],
    listeners: {
      start(event) {
        var interaction = event.interaction;
        if (event.currentTarget.getAttribute('clonable') != 'false') {
          var original = event.currentTarget;
          var clone = event.currentTarget.cloneNode(true);
          var x = clone.offsetLeft;
          var y = clone.offsetTop;
          clone.setAttribute('clonable', 'false');
          clone.style.position = "absolute";
          clone.style.left = original.offsetLeft + "px";
          clone.style.top = original.offsetTop + "px";
          original.parentElement.appendChild(clone);
          interaction.start({
            name: 'drag'
          }, event.interactable, clone);
        }
      },
      move(event) {
        var target = event.target;
        var x = (parseFloat(target.getAttribute('data-x')) || 0) + event.dx;
        var y = (parseFloat(target.getAttribute('data-y')) || 0) + event.dy;

        target.style.transform = 'translate(' + x + 'px, ' + y + 'px)';

        target.setAttribute('data-x', x);
        target.setAttribute('data-y', y);
      }
    },
    autoScroll: true
  });

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接