javascript - 无法使用interact.js拖放到另一个div
问题描述
Html/css 新手在这里,
我正在使用interact.js来获得某个 UI,我可以在其中将项目从列表中拖放到拖放区中。问题是我的列表可能会变得很长,我需要将滚动添加到列表中,当我尝试这样做时,我创建了一个“div”并将列表项放入其中以显示滚动行为。
但是,当我将列表项放在 div 内并将放置区放在它之外时,这些项目不会被放置在那里并且列表显示出一种奇怪的行为,所有这些项都开始堆叠在底部列表项的顶部(在包含项目的 div)。
这是我的html:
<div class="items">
<p style="padding-top: 20px; font-size:18px">Stacked Items</p>
<div style = "height: 400px; overflow: scroll">
<div id="itemstodrop" class="drag-drop"> item 1 </div>
<div id="itemstodrop" class="drag-drop"> item 2 </div>
<div id="itemstodrop" class="drag-drop"> item 3 </div>
<div id="itemstodrop" class="drag-drop"> item 4 </div>
<div id="itemstodrop" class="drag-drop"> item 5 </div>
<div id="itemstodrop" class="drag-drop"> item 6 </div>
<div id="itemstodrop" class="drag-drop"> item 7 </div>
<div id="itemstodrop" class="drag-drop"> item 8 </div>
<div id="itemstodrop" class="drag-drop"> item 9 </div>
<div id="itemstodrop" class="drag-drop"> item 10 </div>
<div id="itemstodrop" class="drag-drop"> item 11 </div>
<div id="itemstodrop" class="drag-drop"> item 12 </div>
</div>
<div id="inner-dropzone" class="dropzone">Drop here</div>
</div>
这是我的包含 interact.js 代码的脚本:
import interact from
'https://cdn.jsdelivr.net/npm/@interactjs/interactjs/index.js'
// enable draggables to be dropped into this
var startPos = null;
//define the initial position for each rig tile.
function dragMoveListener (event) {
var target = event.target
// keep the dragged position in the data-x/data-y attributes
var x = (parseFloat(target.getAttribute('data-x')) || 0) + event.dx
var y = (parseFloat(target.getAttribute('data-y')) || 0) + event.dy
// translate the element
target.style.webkitTransform =
target.style.transform =
'translate(' + x + 'px, ' + y + 'px)'
// update the posiion attributes
target.setAttribute('data-x', x)
target.setAttribute('data-y', y)
}
// this function is used later in the resizing and gesture demos
window.dragMoveListener = dragMoveListener
//ALL THE FUNCTIONS BELOW TALK ABOUT THE DRAGGABLE AREA.
interact('.dropzone').dropzone({
// only accept elements matching this CSS selector
accept: '#itemstodrop',
// the item should go 100% inside the draggable area...
overlap: 0.9999999, //somehow it does not take the value 100%
// listen for drop related events:
ondropactivate: function (event) {
// add active dropzone feedback
event.target.classList.add('drop-active')
},
ondragenter: function (event) {
//when item enters the draggable area
var draggableElement = event.relatedTarget
var dropzoneElement = event.target
console.log(draggableElement.firstChild.nodeValue);
// feedback the possibility of a drop
dropzoneElement.classList.add('drop-target')
draggableElement.classList.add('can-drop')
},
ondragleave: function (event) {
console.log(startPos)
event.draggable.draggable({
snap: {
targets: [startPos]
}
});
//when item leaves the draggable area
// remove the drop feedback style
event.target.classList.remove('drop-target')
event.relatedTarget.classList.remove('can-drop')
},
ondrop: function (event) {
//when the item is droppd in the draggable area
{% comment %} event.relatedTarget.textContent = 'Dropped' {% endcomment %}
},
ondropdeactivate: function (event) {
// remove active dropzone feedback
event.target.classList.remove('drop-active')
event.target.classList.remove('drop-target')
}
})
interact('.drag-drop')
.draggable({
inertia: true,
modifiers: [
interact.modifiers.restrictRect({
restriction: 'parent',
endOnly: true
})
],
autoScroll: true,
// dragMoveListener from the dragging demo above
listeners: { move: dragMoveListener }
})
</script>
这是渲染时的样子:(基本上不能将任何项目拖放到放置区域。)
演示的完整工作页面:(我添加了一条评论,告诉我将 div 放在哪里。)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
#outer-dropzone {
height: 140px;
}
#inner-dropzone {
height: 80px;
}
.dropzone {
background-color: #ccc;
border: dashed 4px transparent;
border-radius: 4px;
margin: 10px auto 30px;
padding: 10px;
width: 80%;
transition: background-color 0.3s;
}
.drop-active {
border-color: #aaa;
}
.drop-target {
background-color: #29e;
border-color: #fff;
border-style: solid;
}
.drag-drop {
display: inline-block;
min-width: 40px;
padding: 2em 0.5em;
color: #fff;
background-color: #29e;
border: solid 2px #fff;
touch-action: none;
-webkit-transform: translate(0px, 0px);
transform: translate(0px, 0px);
transition: background-color 0.3s;
}
.drag-drop.can-drop {
color: #000;
background-color: #4e4;
}
</style>
</head>
<body>
{% comment %} I NEED THIS DIV UNDER THIS COMMENT, TO ADD A SCROLL AREA. BUT WHEN I GIVE THIS DIV, THE DROP DOES NOT OCCUR. {% endcomment %}
<div>
<div id="no-drop" class="drag-drop"> #no-drop </div>
<div id="yes-drop" class="drag-drop"> #yes-drop </div>
</div>
<div id="outer-dropzone" class="dropzone">
#outer-dropzone
<div id="inner-dropzone" class="dropzone">#inner-dropzone</div>
</div>
<script type="module">
import interact from
'https://cdn.jsdelivr.net/npm/@interactjs/interactjs/index.js'
// enable draggables to be dropped into this
interact('.draggable')
.draggable({
// enable inertial throwing
inertia: true,
// keep the element within the area of it's parent
modifiers: [
interact.modifiers.restrictRect({
restriction: 'parent',
endOnly: true
})
],
// enable autoScroll
autoScroll: true,
listeners: {
// call this function on every dragmove event
move: dragMoveListener,
// call this function on every dragend event
end (event) {
var textEl = event.target.querySelector('p')
textEl && (textEl.textContent =
'moved a distance of ' +
(Math.sqrt(Math.pow(event.pageX - event.x0, 2) +
Math.pow(event.pageY - event.y0, 2) | 0))
.toFixed(2) + 'px')
}
}
})
function dragMoveListener (event) {
var target = event.target
// keep the dragged position in the data-x/data-y attributes
var x = (parseFloat(target.getAttribute('data-x')) || 0) + event.dx
var y = (parseFloat(target.getAttribute('data-y')) || 0) + event.dy
// translate the element
target.style.webkitTransform =
target.style.transform =
'translate(' + x + 'px, ' + y + 'px)'
// update the posiion attributes
target.setAttribute('data-x', x)
target.setAttribute('data-y', y)
}
// this function is used later in the resizing and gesture demos
window.dragMoveListener = dragMoveListener
//ALL THE FUNCTIONS BELOW TALK ABOUT THE DRAGGABLE AREA.
interact('.dropzone').dropzone({
// only accept elements matching this CSS selector
accept: '#yes-drop',
// the item should go 100% inside the draggable area...
overlap: 0.9999999, //somehow it does not take the value 100%
// listen for drop related events:
ondropactivate: function (event) {
// add active dropzone feedback
event.target.classList.add('drop-active')
},
ondragenter: function (event) {
//when item enters the draggable area
var draggableElement = event.relatedTarget
var dropzoneElement = event.target
console.log(draggableElement.firstChild.nodeValue);
// feedback the possibility of a drop
dropzoneElement.classList.add('drop-target')
draggableElement.classList.add('can-drop')
},
ondragleave: function (event) {
//when item leaves the draggable area
// remove the drop feedback style
event.target.classList.remove('drop-target')
event.relatedTarget.classList.remove('can-drop')
},
ondrop: function (event) {
//when the item is droppd in the draggable area
{% comment %} event.relatedTarget.textContent = 'Dropped' {% endcomment %}
},
ondropdeactivate: function (event) {
// remove active dropzone feedback
event.target.classList.remove('drop-active')
event.target.classList.remove('drop-target')
}
})
interact('.drag-drop')
.draggable({
inertia: true,
modifiers: [
interact.modifiers.restrictRect({
restriction: 'parent',
endOnly: true
})
],
autoScroll: true,
// dragMoveListener from the dragging demo above
listeners: { move: dragMoveListener }
})
</script>
</body>
</html>
解决方案
您需要更改accept: '#rigstodrop'
为,accept: '#itemstodrop'
因为这里您的 div 具有itemstodrop
您需要拖放的 id 。另外,用于restriction: '.items'
限制 rect 不超出该区域。
演示代码:
var startPos = null;
//define the initial position for each rig tile.
function dragMoveListener(event) {
var target = event.target
// keep the dragged position in the data-x/data-y attributes
var x = (parseFloat(target.getAttribute('data-x')) || 0) + event.dx
var y = (parseFloat(target.getAttribute('data-y')) || 0) + event.dy
// translate the element
target.style.webkitTransform =
target.style.transform =
'translate(' + x + 'px, ' + y + 'px)'
// update the posiion attributes
target.setAttribute('data-x', x)
target.setAttribute('data-y', y)
}
// this function is used later in the resizing and gesture demos
window.dragMoveListener = dragMoveListener
interact('.dropzone').dropzone({
// only accept elements matching this CSS selector
accept: '#itemstodrop', //change this
// the item should go 100% inside the draggable area...
overlap: 0.9999999,
ondropactivate: function(event) {
// add active dropzone feedback
event.target.classList.add('drop-active')
},
ondragenter: function(event) {
//when item enters the draggable area
var draggableElement = event.relatedTarget
var dropzoneElement = event.target
console.log(draggableElement.firstChild.nodeValue);
// feedback the possibility of a drop
dropzoneElement.classList.add('drop-target')
draggableElement.classList.add('can-drop')
},
ondragleave: function(event) {
console.log(startPos)
event.draggable.draggable({
snap: {
targets: [startPos]
}
});
//when item leaves the draggable area
// remove the drop feedback style
event.target.classList.remove('drop-target')
event.relatedTarget.classList.remove('can-drop')
},
ondrop: function(event) {
//when the item is droppd in the draggable area
event.relatedTarget.textContent = 'Dropped'
},
ondropdeactivate: function(event) {
// remove active dropzone feedback
event.target.classList.remove('drop-active')
event.target.classList.remove('drop-target')
}
})
interact('.drag-drop')
.draggable({
inertia: true,
modifiers: [
interact.modifiers.restrictRect({
restriction: '.items', //change this
endOnly: true
})
],
autoScroll: true,
// dragMoveListener from the dragging demo above
listeners: {
move: dragMoveListener
}
})
.itemstodrop {
touch-action: none;
user-select: none;
}
#inner-dropzone {
height: 80px;
}
.dropzone {
background-color: #ccc;
border: dashed 4px transparent;
border-radius: 4px;
margin: 10px auto 30px;
padding: 10px;
width: 80%;
transition: background-color 0.3s;
}
.drop-active {
border-color: #aaa;
}
.drop-target {
background-color: #29e;
border-color: #fff;
border-style: solid;
}
.drag-drop {
display: inline-block;
min-width: 40px;
padding: 2em 0.5em;
color: #fff;
background-color: #29e;
border: solid 2px #fff;
touch-action: none;
-webkit-transform: translate(0px, 0px);
transform: translate(0px, 0px);
transition: background-color 0.3s;
}
.drag-drop.can-drop {
color: #000;
background-color: #4e4;
}
<script src="https://cdn.jsdelivr.net/npm/interactjs/dist/interact.min.js"></script>
<div class="items">
<p style="padding-top: 20px; font-size:18px">Stacked Rigs</p>
<div style="height: auto;overflow: scroll">
<div id="itemstodrop" class="drag-drop itemstodrop"> item 1 </div>
<div id="itemstodrop" class="drag-drop itemstodrop"> item 2 </div>
<div id="itemstodrop" class="drag-drop itemstodrop"> item 3 </div>
<div id="itemstodrop" class="drag-drop itemstodrop"> item 4 </div>
<div id="itemstodrop" class="drag-drop itemstodrop"> item 5 </div>
<div id="itemstodrop" class="drag-drop itemstodrop"> item 6 </div>
<div id="itemstodrop" class="drag-drop itemstodrop"> item 7 </div>
<div id="itemstodrop" class="drag-drop itemstodrop"> item 8 </div>
<div id="itemstodrop" class="drag-drop itemstodrop"> item 9 </div>
<div id="itemstodrop" class="drag-drop itemstodrop"> item 10 </div>
<div id="itemstodrop" class="drag-drop itemstodrop"> item 11 </div>
<div id="itemstodrop" class="drag-drop itemstodrop"> item 12 </div>
<!--put this inside div-->
<div id="inner-dropzone" class="dropzone">Drop here</div>
</div>
</div>
推荐阅读
- html - 如何使用溢出自动仅停止第一个 li 在 ul li 列表中滚动?
- tensorflow - 如何更改 retrain.py 以获取 b64 图像
- python - 计算单词中字母的出现次数到熊猫数据框
- java - 我的 PITEST 不会运行。覆盖生成minion异常退出。我需要帮助才能正确配置我的 pom.xml
- python-3.x - pycharm 2019 优化导入后 Matplotlib 和 numpy 导入不起作用
- c# - 如何在不枚举数据的情况下进行异步查询?
- bash - 如何将多列拆分为几列?
- ocaml - 为什么只需要迭代有限流时这个程序不会停止?
- c# - 一对一关系 EF6 和主键的问题
- python - 如何将密码转换为哈希值?