提问人:Oscar R 提问时间:2/1/2023 更新时间:2/1/2023 访问量:51
为什么使用拖放 API 删除元素后,我的 eventlistener 被删除
Why is my eventlistener being removed after an element has been dropped using drag / drop API
问:
下面我有一个简化版本的代码,我可以在其中单击按钮来添加新元素。这些元素都应该是可拖动的,这样它们就可以交换位置,并且它们还应该具有在单击它们的位置时要删除的功能。我已经成功地实现了这一点,正如你通过运行我的片段所看到的......除了一件事......
如果您尝试在将它换成任何东西之前单击中间的按钮区域,它就像我想要的那样工作。
但是,如果您在交换它后尝试单击它,它将不再起作用。请帮我解决这个问题!
const btn_add_element = document.querySelector('.btn_add_element');
const my_draggable_elements = document.querySelector('.my_draggable_elements');
function handleDragStart(e) {
this.style.opacity = '0.4';
dragSrcEl = this;
e.dataTransfer.effectAllowed = 'move';
e.dataTransfer.setData('text/html', this.innerHTML);
}
function handleDragEnd(e) {
this.style.opacity = '1'; my_draggable_elements.querySelectorAll('.container').forEach(elm => {
elm.classList.remove('dragged_over');
});
}
function handleDragOver(e) {
e.preventDefault();
return false;
}
function handleDragEnter(e) {
this.classList.add('dragged_over');
}
function handleDragLeave(e) {
this.classList.remove('dragged_over');
}
function handleDrop(e) {
e.stopPropagation();
if (dragSrcEl !== this) {
dragSrcEl.innerHTML = this.innerHTML;
this.innerHTML = e.dataTransfer.getData('text/html');
}
return false;
}
function getRandomColor() { return '#'+Math.floor(Math.random()*16777215).toString(16); }
function add_element() {
// Create Container & Make it draggable
const new_container = document.createElement('div');
new_container.classList.add('container');
new_container.setAttribute('draggable', true);
new_container.addEventListener('dragstart', handleDragStart);
new_container.addEventListener('dragover', handleDragOver);
new_container.addEventListener('dragenter', handleDragEnter);
new_container.addEventListener('dragleave', handleDragLeave);
new_container.addEventListener('dragend', handleDragEnd);
new_container.addEventListener('drop', handleDrop);
// Create Content
const new_content = document.createElement('div');
new_content.classList.add('content');
new_content.style.color = getRandomColor();
new_content.innerText = 'Click to Delete';
new_content.addEventListener('click', () => {
new_container.remove();
});
new_container.appendChild(new_content);
my_draggable_elements.appendChild(new_container);
}
btn_add_element.addEventListener('click', () => add_element());
btn_add_element.click();
btn_add_element.click();
btn_add_element.click();
.my_draggable_elements {
display: flex;
gap: 0.5rem;
flex-wrap: wrap;
}
.container {
padding: 2rem;
border: 0.1rem solid black;
cursor: grab;
}
.container.dragged_over {
border: 0.1rem dashed black;
}
.container > .content {
background-color: #ddd;
padding: 0.25rem;
cursor: pointer;
}
.btn_add_element {
margin-top: 2rem;
width: 100%;
text-align: center;
padding: 0.5rem;
}
<div class='my_draggable_elements'></div>
<button class='btn_add_element'>Add Element</button>
答:
在元素中,get's transfer from to the innerHTML of the element is placed to the element of the element is placed to the element of the element gets transfer to the element of the element is stored to the element在这种情况下,eventListener 丢失了。您必须再次添加它,如下面修改后的代码片段所示。handleDrop()
event.dataTransfer.getData('text/html')
const btn_add_element = document.querySelector('.btn_add_element');
const my_draggable_elements = document.querySelector('.my_draggable_elements');
function handleDragStart(e) {
this.style.opacity = '0.4';
dragSrcEl = this;
e.dataTransfer.effectAllowed = 'move';
e.dataTransfer.setData('text/html', this.innerHTML);
}
function handleDragEnd(e) {
this.style.opacity = '1'; my_draggable_elements.querySelectorAll('.container').forEach(elm => {
elm.classList.remove('dragged_over');
});
}
function handleDragOver(e) {
e.preventDefault();
return false;
}
function handleDragEnter(e) {
this.classList.add('dragged_over');
}
function handleDragLeave(e) {
this.classList.remove('dragged_over');
}
function handleDrop(e) {
e.stopPropagation();
if (dragSrcEl !== this) {
dragSrcEl.innerHTML = this.innerHTML;
console.log(this.innerHTML);
this.innerHTML = e.dataTransfer.getData('text/html');
this.addEventListener('click', () => {
this.remove();
});
}
return false;
}
function getRandomColor() { return '#'+Math.floor(Math.random()*16777215).toString(16); }
function add_element() {
// Create Container & Make it draggable
const new_container = document.createElement('div');
new_container.classList.add('container');
new_container.setAttribute('draggable', true);
new_container.addEventListener('dragstart', handleDragStart);
new_container.addEventListener('dragover', handleDragOver);
new_container.addEventListener('dragenter', handleDragEnter);
new_container.addEventListener('dragleave', handleDragLeave);
new_container.addEventListener('dragend', handleDragEnd);
new_container.addEventListener('drop', handleDrop);
// Create Content
const new_content = document.createElement('div');
new_content.classList.add('content');
new_content.style.color = getRandomColor();
new_content.innerText = 'Click to Delete';
new_content.addEventListener('click', () => {
new_container.remove();
});
new_container.appendChild(new_content);
my_draggable_elements.appendChild(new_container);
}
btn_add_element.addEventListener('click', () => add_element());
btn_add_element.click();
btn_add_element.click();
btn_add_element.click();
.my_draggable_elements {
display: flex;
gap: 0.5rem;
flex-wrap: wrap;
}
.container {
padding: 2rem;
border: 0.1rem solid black;
cursor: grab;
}
.container.dragged_over {
border: 0.1rem dashed black;
}
.container > .content {
background-color: #ddd;
padding: 0.25rem;
cursor: pointer;
}
.btn_add_element {
margin-top: 2rem;
width: 100%;
text-align: center;
padding: 0.5rem;
}
<div class='my_draggable_elements'></div>
<button class='btn_add_element'>Add Element</button>
评论
在@anarchist912的帮助下,我终于得到了想要的结果。
正如他在回答中所说,用于删除元素的事件侦听器在 handleDrop 函数中丢失。为了解决这个问题,我们必须再次手动添加 eventlistener。
this.addEventListener('click', () => {
this.remove();
});
然而,这显然是不够的。
我不小心解决了这个问题,为我的个人用例编写了一个 remove_element() 函数并让它工作,然后当我使用上面的箭头函数在代码段中测试它时意识到它在这里不起作用。因此,以下是使其起作用的更改:
function remove_element(e) {
e.target.closest('.container').remove();
}
// and inside handleDrop()
dragSrcEl.querySelector('.content').addEventListener('click', remove_element);
this.querySelector('.content').addEventListener('click', remove_element);
const btn_add_element = document.querySelector('.btn_add_element');
const my_draggable_elements = document.querySelector('.my_draggable_elements');
function handleDragStart(e) {
this.style.opacity = '0.4';
dragSrcEl = this;
e.dataTransfer.effectAllowed = 'move';
e.dataTransfer.setData('text/html', this.innerHTML);
}
function handleDragEnd(e) {
this.style.opacity = '1'; my_draggable_elements.querySelectorAll('.container').forEach(elm => {
elm.classList.remove('dragged_over');
});
}
function handleDragOver(e) {
e.preventDefault();
return false;
}
function handleDragEnter(e) {
this.classList.add('dragged_over');
}
function handleDragLeave(e) {
this.classList.remove('dragged_over');
}
function handleDrop(e) {
e.stopPropagation();
if (dragSrcEl !== this) {
dragSrcEl.innerHTML = this.innerHTML;
dragSrcEl.querySelector('.content').addEventListener('click', remove_element);
this.innerHTML = e.dataTransfer.getData('text/html');
this.querySelector('.content').addEventListener('click', remove_element);
}
return false;
}
function getRandomColor() { return '#'+Math.floor(Math.random()*16777215).toString(16); }
function remove_element(e) {
e.target.closest('.container').remove();
}
function add_element() {
// Create Container & Make it draggable
const new_container = document.createElement('div');
new_container.classList.add('container');
new_container.setAttribute('draggable', true);
new_container.addEventListener('dragstart', handleDragStart);
new_container.addEventListener('dragover', handleDragOver);
new_container.addEventListener('dragenter', handleDragEnter);
new_container.addEventListener('dragleave', handleDragLeave);
new_container.addEventListener('dragend', handleDragEnd);
new_container.addEventListener('drop', handleDrop);
// Create Content
const new_content = document.createElement('div');
new_content.classList.add('content');
new_content.style.color = getRandomColor();
new_content.innerText = 'Click to Delete';
new_content.addEventListener('click', remove_element);
new_container.appendChild(new_content);
my_draggable_elements.appendChild(new_container);
}
btn_add_element.addEventListener('click', () => add_element());
btn_add_element.click();
btn_add_element.click();
btn_add_element.click();
.my_draggable_elements {
display: flex;
gap: 0.5rem;
flex-wrap: wrap;
}
.container {
padding: 2rem;
border: 0.1rem solid black;
cursor: grab;
}
.container.dragged_over {
border: 0.1rem dashed black;
}
.container > .content {
background-color: #ddd;
padding: 0.25rem;
cursor: pointer;
}
.btn_add_element {
margin-top: 2rem;
width: 100%;
text-align: center;
padding: 0.5rem;
}
<div class='my_draggable_elements'></div>
<button class='btn_add_element'>Add Element</button>
评论