Как повесить обработчик событий 'click' на элемент который создается в js и взаимодействует с базой данных
Есть слайдер, в котором находятся карточки которые создаются в js а значения приходят с сервера. В карточках есть элемент, на который нужно повесить обработчик событий, но как только не пробовал, ничего не получается. (нужно повесить на элемент cards__input__plus). Хотел вставить пример кода, но из-за того что данные приходят с сервера, смысла в html и css нет. Все есть в js, элементы с классами на которые хочу повесить обработчик событий тоже есть в js
function cards() {
// Используем классы для карточек
class MenuCard {
constructor(src, srcSale, srcNew, srcRecommend, availability, code, text, newPrice, price, parentSelector, ...classes) {
this.src = src;
this.srcSale = srcSale;
this.srcNew = srcNew;
this.srcRecommend = srcRecommend;
this.availability= availability;
this.code = code;
this.text = text;
this.newPrice = newPrice;
this.price = price;
this.classes = classes; // мы не знаем сколько будет аргументов в будущем
this.parent = document.querySelector(parentSelector); //обязательно получаем только 1 элемент
}
render() {
const element = document.createElement('div'); //создаем какой-то блок
if (this.classes.length === 0) {
this.element = "cards__item";
element.classList.add(this.element);
sliderTwo();
} else {
this.classes.forEach(className => element.classList.add(className));
//мы перебираем весь массив, и присваем className каждому элементу
} // если у нас ничего не добавляется, ты мы добавляем сами "cards__item"
// Если же у нас есть что-то, то мы перебираем через forEach, так как у нас это массив
element.innerHTML = `
<img src=${this.src} alt="" class="cards__logo">
<svg data-close class="cards__favorites">
<use xlink:href="#favorites"></use>
</svg>
<div class="cards__imgs">
<img src=${this.srcSale} alt="" class="cards__sale">
<img src=${this.srcNew} alt="" class="cards__new">
<img src=${this.srcRecommend} alt="" class="cards__recommend">
</div>
<div class="cards__item__info">
<p class="cards__availability">${this.availability}</p>
<p class="cards__code">${this.code}</p>
</div>
<p class="cards__item__text">${this.text}</p>
<div class="cards__item__info__price">
<p class="cards__new__price">${this.newPrice}</p>
<p class="cards__price">${this.price}</p>
<img src="img/cards/cards-5.png" alt="" class="cards__basket">
</div>
<div class="cards__form">
<div type="text" class="cards__input"></div>
<div class="cards__input__minus">
<img src="img/cards/minus.png" alt="" class="minus">
</div>
<p class="cards__input__text">0</p>
<div class="cards__input__plus">
<img src="img/cards/plus.png" alt="" class="plus">
</div>
</div>
<div class="cards__btns">
<button class="btn btn-one">Купить в 1 клик</button>
<button class="btn btn-two">В корзину</button>
</div>
`;
this.parent.append(element); // добавляем в самый конец своего родителя
}
}
getResource('http://localhost:3000/cards')
.then(data => { // data Это большой массив из db.json
data.forEach(({src, srcSale, srcNew, srcRecommend, availability, code, text, newPrice, price}) =>{
new MenuCard(src, srcSale, srcNew, srcRecommend, availability, code, text, newPrice, price, '.cards__slider .cards__inner').render();
});// Этот конструктор будет создаваться столько раз, сколько объектов внутри массива
// который мне придет из сервера
});
}
const getResource = async (url) => { //В функции будет какойто асинхронный код, поэтому мы написали async
const res = await fetch(url); // тут мы пишем куда // использовали его парный оператор await, перед теми
// операциями, которые нужно дождаться. Эти операторы всегда используются в паре!
if(!res.ok) {
throw new Error(`Coul not fetch ${url}, status: ${res.status}`); // Это на слуяай если будет ошибка
}
return await res.json(); //Дожидается работы этого промиса и только потом его возвращает
};
cards();
// Price
function price() {
const plus = document.querySelectorAll('.cards__input__plus');
plus.forEach(item => {
item.addEventListener('click', () => {
console.log('fsdfsdf');
});
});
}
price();
Ответы (2 шт):
Автор решения: Павел
→ Ссылка
Оказалось что элементы на странице все же появлялись не асинхронно, поэтому я воспользовался setTimeout на вызов функции события и все заработало:
setTimeout(() => {
price();
}, 400);
Автор решения: Igor
→ Ссылка
element.innerHTML = `
...
`;
element.querySelectorAll('.cards__input__plus').forEach(item => {
item.addEventListener('click', () => {
console.log('fsdfsdf');
});
});