Javascript 为什么';t removeEventListener删除关联函数

Javascript 为什么';t removeEventListener删除关联函数,javascript,dom-events,Javascript,Dom Events,您好,我正在尝试制作一个svg编辑器,在这里我可以创建和拖动我创建的矩形。每次触发mouseDown事件时,我都会向svg元素(mouseMove和mouseUp)添加两个事件监听器,每次调用mouseUp时,我都会尝试删除这些事件,但由于删除不起作用,因此元素附带了多个mouseMove和mouseUp监听器。我不知道怎么了MouseDown做两件事,首先它可以绘制矩形,然后如果createMode为false,让我拖动它们 this.domElement.addEventListene

您好,我正在尝试制作一个svg编辑器,在这里我可以创建和拖动我创建的矩形。每次触发
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方面没有太多经验,但是我的直觉告诉我要依赖全局状态(比如你提到的布尔变量)和通用事件侦听器,而不是在每个绘制的形状上单独添加和删除它们。拖放行为在原则上可能是相同的,它只会影响屏幕上的不同形状。。如果这有道理的话。