I am creating and appending elements via class object constructor with a button press, and need each individual element created to have an event listener that will call a method from a class to return the values of the object tied to the element.
Everything seems to work fine when I have a single element that was created. When I have two or more elements, it will output n results where n = the amount of elements that were created. 4 elements created = 4x the outputs, which ruins anything that I want to do with the data output.
For example, if I have one element that has the properties of square and red, then clicking it correctly outputs square and red. But if I add an element with the object properties of circle and green, then clicking on EITHER element will output both 'square red' and 'circle green'
// Utility function
function onEvent(event, selector, callback) {
return selector.addEventListener(event, callback);
}
onEvent('click', submit, function() {
let shape = new Shape(shapeInput.value, colorInput.value);
shape.createShape();
output.innerHTML = `${shape.shapeColor} ${shape.shapeName} `
shapeContainer.addEventListener('click', function (e) {
let target = e.target;
if (target.matches('div')) {
output.innerHTML = `${shape.getInfo()}`;
}
});
});
I have tried looking for ways to check if the element already has an event listener and to ignore it, but didn't have any luck. I have also tried to add a removeEventListener
section, to no success. Is there something I'm missing here or am I completely wrong with my approach?
CodePudding user response:
Hope I did not respond let. this will work for you.
'use strict';
// Selectors
const shapeContainer = select('.shape-container');
const submit = select('.submit');
const shapeInput = select('.shape-input');
const colorInput = select('.color-input');
const shapeSelector = select('.shape');
const output = select('span');
class Shape {
constructor(name, color) {
this._name = name;
this._color = color;
}
set shapeName(name) {
if (name instanceof Shape && this._name.length > 0) {
this._name = name;
} else {
throw new TypeError('Shape name is invalid');
}
}
get shapeName() {
return this._name;
}
set shapeColor(color) {
if (color instanceof Shape && this._color.length > 0) {
this._color = color;
} else {
throw new TypeError('Color is invalid');
}
}
get shapeColor() {
return this._color;
}
createShape() {
let element = {
tag : document.createElement('div'),
color : this._color,
name : this._name,
}
document.querySelector('.shape-container').appendChild(element.tag);
element.tag.style.cssText = 'background-color:' element.color;
// Shape definition
if (this._name == 'circle') {
element.tag.classList.add('circle', 'shape');
} else if (this._name == 'square') {
element.tag.classList.add('square', 'shape');
} else {
throw new TypeError('shapeName is invalid');
}
element.tag.addEventListener('click', function () {
console.log(element.color," ",element.name)
if (element.tag.matches('div')) {
output.innerHTML = getInfo(element);
}
});
}
}
// Utility functions
function select(selector, parent = document) {
return parent.querySelector(selector);
}
function onEvent(event, selector, callback) {
return selector.addEventListener(event, callback);
}
function getInfo (e) {
console.log(e.color,e.name)
return `${e.name} ${e.color}`;
}
let arr = [];
onEvent('click', submit, function () {
let shape = new Shape(shapeInput.value, colorInput.value);
arr.push(shape);
console.log(arr);
shape.createShape();
});