我正在尝试创建一个看板(类似于trello)的简单网站来学习javascript。我已经使用了拖放功能,但是,我正努力添加新卡,并将多张卡移动到不同列表中的不同位置。
第一张卡(从头开始在HTML中实现,而不是由DOM添加)可以正常工作。我可以将这张卡移动到任何需要的地方。
我的代码有两个问题:
addCard()
和addTaskContainer()
的函数,以便能够添加新任务。元素被创建,但是每当我尝试移动此卡时,第一张原始卡将被移到放置位置,而不是DOM被创建。addCard()
函数添加多张卡片,则该卡片似乎堆叠在同一div中。我意识到我需要删除最初添加的ID,但是如果再次按下该按钮,我将无法添加新的ID。我希望包含不同卡的列表始终为新添加的卡提供+1任务容器。
我尝试在addTaskContainer()
函数中设置id = "";
的{{1}},但是在单击按钮时无法将其重新添加到addCard()
。
我还尝试过像这样遍历卡片中的卡片:
addTaskContainer()
和类似的卡片:
for (const card in cards) {
card.addEventListener('dragstart', dragStart);
card.addEventListener('dragend', dragEnd);
}
没有运气。
for (const card of cards) {
card.addEventListener('dragstart', dragStart);
card.addEventListener('dragend', dragEnd);
}
<div class="lists">
<div class="list">
<div class="list-header">
<p>Backlog</p>
</div>
<div class="list-body" id="backlog">
<p>body</p>
<div class="taskContainer">
<div class="card" draggable="true"> </div>
</div>
<div class="taskContainer">
<div class="card" draggable="true"> </div>
</div>
<div class="taskContainer">
</div>
</div>
<div class="list-footer">
<p>footer</p>
<button onclick="addCard()">Add ned card</button>
</div>
</div>
</div>
答案 0 :(得分:1)
您发布的代码存在两个问题:
您使用id
来标识元素,页面上每个id
只能有一个元素。这意味着当您通过id
获得元素时,它可能是旧卡片。一种方法是在完成拖动操作后删除ID,但更简单的方法是将卡存储在变量draggingCard
您没有将侦听器添加到函数中新创建的cards
和taskContainers
中。
我还添加了一些样式,以使所有内容更易于查看: https://codepen.io/anon/pen/XwqpKg
HTML:
<div class="lists">
<div class="list">
<div class="list-header">
<p>Backlog</p>
</div>
<div class="list-body" id="backlog">
<p>body</p>
<div class="taskContainer">
<div class="card" draggable="true"> </div>
</div>
<div class="taskContainer">
<div class="card" draggable="true"> </div>
</div>
<div class="taskContainer">
</div>
</div>
<div class="list-footer">
<p>footer</p>
<button onclick="addCard()">Add ned card</button>
</div>
</div>
</div>
CSS:
.card {
display: inline-block;
padding: 8px;
cursor: pointer;
border-radius: 4px;
box-shadow: 0 0 1px 1px rgba(0, 0, 0, 0.25);
}
.card-dragging {
display: absolute;
}
.taskContainer {
display: inline-block;
background: skyblue;
padding: 8px;
min-width: 16px;
min-height: 16px;
}
JavaScript:
const card = document.querySelector('.card');
const cards = document.querySelectorAll('.card')
const taskContainers = document.querySelectorAll('.taskContainer');
var draggingCard = null;
// card listeners
cards.forEach(addCardListeners);
// Loop through taskContainer boxes and add listeners
taskContainers.forEach(addContainerListeners);
// Drag Functions
function dragStart(event) {
this.className += ' hold';
setTimeout(() => (this.className = 'invisible'), 0); //set timeout so card wont dissapear
draggingCard = event.target;
}
function dragEnd() {
this.className = 'card';
draggingCard = null;
}
function dragOver(e) {
e.preventDefault();
}
function dragEnter(e) {
e.preventDefault();
this.className += ' hover';
}
function dragLeave() {
this.className = 'taskContainer';
}
function dragDrop() {
this.className = 'taskContainer';
this.append(draggingCard);
}
//add card function
function addTaskContainer() {
var taskContainer = document.createElement('div');
taskContainer.className = "taskContainer";
taskContainer.id = "add-new-card";
addContainerListeners(taskContainer);
document.getElementById("backlog").append(taskContainer);
return taskContainer;
}
function addCard() {
var container = addTaskContainer();
var card = document.createElement('div');
card.className = "card";
card.id = "new-card";
card.setAttribute('draggable', true);
addCardListeners(card);
container.appendChild(card);
}
function addCardListeners(card) {
card.addEventListener('dragstart', dragStart);
card.addEventListener('dragend', dragEnd);
}
function addContainerListeners(taskContainer) {
taskContainer.addEventListener('dragover', dragOver);
taskContainer.addEventListener('dragenter', dragEnter);
taskContainer.addEventListener('dragleave', dragLeave);
taskContainer.addEventListener('drop', dragDrop);
}
答案 1 :(得分:-1)
部分原因是您的投递处理程序仅设计用于处理页面上的第一张卡片。 this.append(card)
将始终将第一张卡片添加到放置区域。您需要检索拖动的元素,然后附加该元素。
正如您将在MDN示例中观察到的那样,在拖动开始事件处理程序中,设置了一个全局变量来标识要拖动的元素。然后,稍后将“拖放”元素附加到放置区。
相关代码:
var dragged;
document.addEventListener("dragstart", function(event) {
// store a ref. on the dragged elem
dragged = event.target;
event.target.style.opacity = .5;
}, false);
document.addEventListener("drop", function(event) {
// prevent default action (open as link for some elements)
event.preventDefault();
// move dragged elem to the selected drop target
if (event.target.className == "dropzone") {
event.target.style.background = "";
dragged.parentNode.removeChild( dragged );
event.target.appendChild( dragged );
}
}, false);
这是您想要做的事情: