Событие Click срабатывает все больше и больше раз

Итак, я пытаюсь создать редактор SVG. Для этой функции я пытаюсь выделить выделенный прямоугольник, рисуя меньшие прямоугольники в каждом из его углов, используя событие onClick. Но каждый раз, когда я нажимаю на прямоугольник, событие срабатывает несколько раз, и каждый раз, когда я нажимаю на него снова, событие срабатывает намного чаще, чем раньше. Я приложил код, но метод endDraw — это тот, где я добавляю прослушиватель событий, когда рисование прямоугольника завершено, а adaugaClick рисует маленькие прямоугольники. В чем проблема, из-за которой событие click срабатывает несколько раз? Пробовал звонить e.stopPropagation();, думал, может это как-то связано с этим, но не получилось

class BarChart {
    constructor(domElement) {

        this.domElement = domElement;
        this.svgns = "http://www.w3.org/2000/svg";
        this.rect = document.createElementNS(this.svgns, 'rect');
    }
    draw() {
        this.domElement.addEventListener("mousedown", (event) => {
            if (event.button === 0) {
                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);
                    rect.setAttribute('y', mouseY);
                    rect.setAttribute('width', width);
                    rect.setAttribute('height', height);
                    rect.setAttribute('stroke', "black");
                    rect.setAttribute('fill', 'white');
                    this.rect = rect;
                    this.domElement.appendChild(rect);
                }

                const endDraw = (e) => {
                    this.domElement.removeEventListener("mousemove", drawRect);
                    this.domElement.removeEventListener("mouseup", () => endDraw(event));
                    this.rect.addEventListener("click", () => this.adaugaClick(e))

                }

                this.domElement.addEventListener("mouseup", endDraw)
                this.domElement.addEventListener("mousemove", drawRect)
            }

        })
        console.dir(this.domElement)
    }

    adaugaClick(e) {
        const dreptunghi = this.creeazaSelect(e);
        for (let rect of dreptunghi)
            this.domElement.appendChild(rect);
    }

    creeazaSelect(event) {
        const forma = event.target;
        const h = "8px";
        const w = "8px";
        const widthForma = parseInt(forma.getAttribute("width"));
        const heightForma = parseInt(forma.getAttribute("height"));
        const xForma = parseInt(forma.getAttribute('x')) - parseInt(w, 10) / 2;
        const yForma = parseInt(forma.getAttribute('y')) - parseInt(w, 10) / 2;
        const dreptunghiuri = [];

        for (let i = 0; i <= 5; i++) {
            const rect = document.createElementNS(this.svgns, 'rect');
            if (i === 0) {
                rect.setAttribute('x', xForma);
                rect.setAttribute('y', yForma);
            }
            else if (i === 1) {
                rect.setAttribute('x', xForma + widthForma / 2);
                rect.setAttribute('y', yForma);
            }
            else if (i === 2) {
                rect.setAttribute('x', (xForma + widthForma));
                rect.setAttribute('y', yForma);
            }
            else if (i === 3) {
                rect.setAttribute('x', xForma);
                rect.setAttribute('y', yForma + heightForma);
            }
            else if (i === 4) {
                rect.setAttribute('x', xForma + widthForma / 2);
                rect.setAttribute('y', yForma + heightForma);
            }
            else if (i === 5) {
                rect.setAttribute('x', (xForma + widthForma));
                rect.setAttribute('y', yForma + heightForma);
            }

            rect.setAttribute('height', h);
            rect.setAttribute("width", w);
            rect.setAttribute('stroke', "black");
            rect.setAttribute("fill", "#00FFFF");
            dreptunghiuri.push(rect);

        }
        return dreptunghiuri;
    }
}
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
0
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ваше событие mousedown запускается каждый раз, когда вы нажимаете на rect. Проблема возникает, когда внутри endDraw вы добавляете eventListener к this.rect. Это приводит к неустойчивому поведению, так как this.rect содержит последний созданный вами прямоугольник, который будет получать все больше и больше eventListeners. Вы можете решить эту проблему, установив this.rect = null; сразу после this.rect.addEventListener("click", () => this.adaugaClick(e));

Большое спасибо за ваш ответ, теперь это кажется таким очевидным.

Siam 23.12.2020 22:49

Рад помочь. Вы можете установить его как принятый, если он отвечает на вопрос.

vqf 24.12.2020 12:12

Другие вопросы по теме