Javascript 为什么';t removeEventListener删除关联函数
您好,我正在尝试制作一个svg编辑器,在这里我可以创建和拖动我创建的矩形。每次触发Javascript 为什么';t removeEventListener删除关联函数,javascript,dom-events,Javascript,Dom Events,您好,我正在尝试制作一个svg编辑器,在这里我可以创建和拖动我创建的矩形。每次触发mouseDown事件时,我都会向svg元素(mouseMove和mouseUp)添加两个事件监听器,每次调用mouseUp时,我都会尝试删除这些事件,但由于删除不起作用,因此元素附带了多个mouseMove和mouseUp监听器。我不知道怎么了MouseDown做两件事,首先它可以绘制矩形,然后如果createMode为false,让我拖动它们 this.domElement.addEventListene
mouseDown
事件时,我都会向svg元素(mouseMove
和mouseUp
)添加两个事件监听器,每次调用mouseUp时,我都会尝试删除这些事件,但由于删除不起作用,因此元素附带了多个mouseMove
和mouseUp
监听器。我不知道怎么了MouseDown
做两件事,首先它可以绘制矩形,然后如果createMode为false,让我拖动它们
this.domElement.addEventListener("mousedown", (event) => {
if (event.button === 0 && this.createMode === true) {
document.body.style.cursor = 'crosshair'
const rect = document.createElementNS(this.svgns, 'rect');
//rect.setAttribute('tabindex', "1");
let first_mouseX = event.clientX;
let first_mouseY = event.clientY;
const drawRect = (event) => {
let mouseX = event.clientX;
let mouseY = event.clientY;
const width = Math.abs(mouseX - first_mouseX);
const height = Math.abs(mouseY - first_mouseY);
if (mouseX > first_mouseX) {
mouseX = first_mouseX;
}
if (mouseY > first_mouseY) {
mouseY = first_mouseY;
}
rect.setAttribute('x', mouseX - this.domElement.getBoundingClientRect().left)
rect.setAttribute('y', mouseY - this.domElement.getBoundingClientRect().top);
rect.setAttribute('width', width);
rect.setAttribute('height', height);
rect.setAttribute('stroke', "black");
rect.setAttribute('fill', 'white');
rect.setAttribute('stroke-width', 2);
this.rect = rect;
this.domElement.appendChild(rect);
}
const endDraw = () => {
this.domElement.removeEventListener("mousemove", drawRect);
this.domElement.removeEventListener("mouseup", endDraw);
if (this.rect !== null) {
this.rect.addEventListener('click', () => {
this.createMode = false;
document.body.style.cursor = "auto"
event.target.focus()
})
this.rect.addEventListener('blur', () => {
this.stergeClick();
})
this.rect.addEventListener("focus", (event) => {
this.stergeClick();
this.adaugaClick(event.target)
})
this.rect.focus();
this.rect = null;
}
}
this.domElement.addEventListener("mouseup", endDraw)
this.domElement.addEventListener("mousemove", drawRect)
} else if (this.createMode === false) {
const startDrag = (event) => {
this.selectedItem = {}
this.selectedItem.item = event.target
this.selectedItem.offsetX = event.clientX - this.selectedItem.item.getAttribute('x');
this.selectedItem.offsetY = event.clientY - this.selectedItem.item.getAttribute('y');
}
startDrag(event)
const drag = (event) => {
if (Object.keys(this.selectedItem).length > 0 && this.createMode === false && this.selectedItem.item.nodeName !== "svg") {
this.stergeClick();
this.adaugaClick(this.selectedItem.item);
this.selectedItem.item.setAttribute('x', event.clientX - this.selectedItem.offsetX);
this.selectedItem.item.setAttribute('y', event.clientY - this.selectedItem.offsetY);
} else {
return false
}
}
const endDrag = (ev) => {
if (Object.keys(this.selectedItem).length > 0 && this.selectedItem.item.nodeName !== "svg") {
this.stergeClick();
this.adaugaClick(this.selectedItem.item);
ev.target.removeEventListener('mouseup', drag);
ev.target.removeEventListener('mousemove', endDrag);
this.domElement.removeEventListener('mouseup', drag);
this.domElement.removeEventListener('mousemove', endDrag);
this.selectedItem = {};
}
}
this.domElement.addEventListener("mousemove", drag);
this.domElement.addEventListener("mouseup", endDrag);
}
})
}为什么删除不起作用?您得到的确切错误是什么?没有错误,如果我在endDrag函数中放置一个console.log(“mouseUp”),它将首先记录消息一次,然后在下一次单击时,它将记录消息2次(总共3次),然后3次(总共6次),等等。所以我认为它只是添加了越来越多的事件监听器,而没有删除它们。看起来您正试图尽早地非常积极地删除事件监听器。在删除一个矩形之前,你不能保持它们的连接吗?无论如何,每次拖动矩形时都必须重新附着它们。也许这会让代码更直截了当一点。另外,请注意:有一种方法可以让侦听器自动运行一次,这样您就不必自己删除它。可以简化您的代码。感谢您的建议,为mouseUp设置once=true非常有用,因为它只需要启动一次,但mouseMove必须能够启动多次。我试图做的是在mouseUp启动后,拖动应该停止,但是selectedItem应该保持选中状态。因此,拖动应该只能在鼠标按下时进行。我还可以使用布尔变量来实现这一点,如果mouseDown被激发,则将其设置为true,如果mouseUp被激发,则将其设置为false。但是我仍然不知道为什么删除不起作用我在构建这样的GUI方面没有太多经验,但是我的直觉告诉我要依赖全局状态(比如你提到的布尔变量)和通用事件侦听器,而不是在每个绘制的形状上单独添加和删除它们。拖放行为在原则上可能是相同的,它只会影响屏幕上的不同形状。。如果这有道理的话,为什么移除不起作用?您得到的确切错误是什么?没有错误,如果我在endDrag函数中放置一个console.log(“mouseUp”),它将首先记录消息一次,然后在下一次单击时,它将记录消息2次(总共3次),然后3次(总共6次),等等。所以我认为它只是添加了越来越多的事件监听器,而没有删除它们。看起来您正试图尽早地非常积极地删除事件监听器。在删除一个矩形之前,你不能保持它们的连接吗?无论如何,每次拖动矩形时都必须重新附着它们。也许这会让代码更直截了当一点。另外,请注意:有一种方法可以让侦听器自动运行一次,这样您就不必自己删除它。可以简化您的代码。感谢您的建议,为mouseUp设置once=true非常有用,因为它只需要启动一次,但mouseMove必须能够启动多次。我试图做的是在mouseUp启动后,拖动应该停止,但是selectedItem应该保持选中状态。因此,拖动应该只能在鼠标按下时进行。我还可以使用布尔变量来实现这一点,如果mouseDown被激发,则将其设置为true,如果mouseUp被激发,则将其设置为false。但是我仍然不知道为什么删除不起作用我在构建这样的GUI方面没有太多经验,但是我的直觉告诉我要依赖全局状态(比如你提到的布尔变量)和通用事件侦听器,而不是在每个绘制的形状上单独添加和删除它们。拖放行为在原则上可能是相同的,它只会影响屏幕上的不同形状。。如果这有道理的话。