Итак, я пытаюсь создать редактор 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;
}
}
Ваше событие mousedown
запускается каждый раз, когда вы нажимаете на rect
. Проблема возникает, когда внутри endDraw
вы добавляете eventListener
к this.rect
. Это приводит к неустойчивому поведению, так как this.rect
содержит последний созданный вами прямоугольник, который будет получать все больше и больше eventListener
s. Вы можете решить эту проблему, установив this.rect = null;
сразу после this.rect.addEventListener("click", () => this.adaugaClick(e));
Рад помочь. Вы можете установить его как принятый, если он отвечает на вопрос.
Большое спасибо за ваш ответ, теперь это кажется таким очевидным.