MayorPlay
@MayorPlay
!developer

Как переинициализировать элементы?

Всем привет, дорогие друзья, у меня есть код на JS, вот эта портянка:
window.onload = init();

function init() {
	const moreButton = document.querySelector('.btn.more');
	const openDescs = document.querySelectorAll(".open_desc");
	let mainRow = document.querySelector(".main .row");
	const cardsLinks = document.querySelectorAll(".card");
	const back = document.querySelector(".product_card_back");
	const modalProduct = document.querySelector(".product_card");
	const cart = document.querySelector(".cart");
	const cartList = document.querySelector(".cart_list");

	window.onkeydown = e => {
		if(e.which == 27) {
			back.classList.add("unactive");
			cartList.classList.add("unactive");
		};
	}

	function initElems() {
		let cartClick = document.querySelectorAll("button.del, a.cart_click");

		cartClick.forEach(elem = elem => {
			if(elem.classList.contains("add_to_cart")) {
				elem.onclick = () => {
					let id = elem.getAttribute("data-id");
					let xhr = new XMLHttpRequest();
					xhr.open("get", `addtocart.php?id=${id}`);
					xhr.send();
					xhr.onreadystatechange = () => {
						if(xhr.status == 200) {
							document.querySelectorAll(`a[data-id='${id}']`).forEach(el = el => {
								el.classList.add('remove_from_cart');
								elem.querySelector(".p").innerHTML = "Удалить";
							});
							document.querySelectorAll(`a[data-id='${id}']`).forEach(el = el => {
								el.classList.remove('add_to_cart');
							});
							if(elem.querySelector(".dot")) {
								elem.querySelector(".dot").innerHTML = "Удалить";
							}
		
							let data = JSON.parse(xhr.responseText);
		
							cartList.innerHTML = "";
							document.querySelector(".cart p").innerHTML = `Товаров в корзине: ${data.length}`;
		
							data.forEach(el = el => {
								cartList.innerHTML += `<div class="product_info">
									<div class='info'>
										<h2 class="title_prod">${el.title}</h2>
										<p class="price_prod">Стоимость: ${el.cost}</p>
									</div>
									<button class="btn del remove_from_cart" data-id="${el.id}">
										<img src="media/close-outline.svg" alt="">
									</button>
								</div>`;
							});
						}
					}
					window.init();
				}
			} else if(elem.classList.contains("remove_from_cart")) {
				elem.onclick = () => {
					let id = elem.getAttribute("data-id");
					let xhr = new XMLHttpRequest();
					xhr.open("get", `remove.php?id=${id}`);
					xhr.send();
					xhr.onreadystatechange = () => {
						if(xhr.status == 200) {
							document.querySelectorAll(`a[data-id='${id}']`).forEach(el = el => {
								el.classList.add("add_to_cart");
								el.querySelector("p").innerHTML = "В корзину";
								
							});
							document.querySelectorAll(`a[data-id='${id}']`).forEach(el = el => {
								el.classList.remove(`remove_from_cart`);
							});
		
							let data = JSON.parse(xhr.responseText);
		
							cartList.innerHTML = "";
							document.querySelector(".cart p").innerHTML = `Товаров в корзине: ${data.length}`;
		
							if(data.length > 0) {
								data.forEach(el = el => {
									cartList.innerHTML += `<div class="product_info">
										<div class='info'>
											<h2 class="title_prod">${el.title}</h2>
											<p class="price_prod">Стоимость: ${el.cost}</p>
										</div>
										<button class="btn del remove_from_cart" data-id="${el.id}">
											<img src="media/close-outline.svg" alt="">
										</button>
									</div>`;
								});
							} else {
								cartList.innerHTML = `<h1 class="title">Корзина пуста :(</h1>`;
							}
						}
						window.init();
					}
				}
			}
		});
	}

	initElems();

	back.onclick = e => {
		if(e.target == back) {
			back.classList.add("unactive");
		}
	};

	cardsLinks.forEach(elem = elem => {
		elem.onclick = e => {
			if(e.target != elem.querySelector(".add_to_cart") || e.target != elem.querySelector(".remove_from_cart")) {
				let id = elem.getAttribute("data-id");
				let title = elem.getAttribute("data-title");
				let cost = elem.getAttribute("data-price");
				let img = elem.getAttribute("data-img");
				modalProduct.querySelector(".product_card_image").src = img;
				modalProduct.querySelector(".product_card_title").innerHTML = title;
				modalProduct.querySelector(".product_card_price").innerHTML = `Стоимость: ${cost}`;
				if(elem.querySelector(".remove_from_cart")) {
					modalProduct.querySelector("a").classList.remove("add_to_cart");
					modalProduct.querySelector("a").classList.add("remove_from_cart");
					modalProduct.querySelector("a").setAttribute('data-id', id);
					modalProduct.querySelector("a").querySelector("p").innerHTML = "Удалить";
				} else if(elem.querySelector(".add_to_cart")) {
					modalProduct.querySelector("a").classList.remove("remove_from_cart");
					modalProduct.querySelector("a").classList.add("add_to_cart");
					modalProduct.querySelector("a").setAttribute('data-id', id);
					modalProduct.querySelector("a").querySelector("p").innerHTML = "В корзину";
				}
				back.classList.remove("unactive");
				initElems();
			}
		}
	});

	cart.onclick = () => {
		document.querySelector(".cart_list").classList.toggle("unactive");
	}
}


В кратце объясню что тут происходит, после загрузки страницы выполняется функция init, которая инициализирует элементы, создает массивы, добавляет их в эти массивы, т.е. всё раскладывает по полочкам. Но есть беда. Смотрите, когда мы нажимаем на одну из кнопок, у нас срабатывает ряд действий, в частности, у неё меняется класс и добавляются новые элементы на страницу. Проблема возникает тогда, когда нужно обновить все данные по элементам, потому-что JS новые элементы не видит, а измененные воспринимает, как старые, со старыми классами, из-за этого возникают конфликты. В функцию инициализации кнопок я сунул всю эту инициализацию и каждый раз ,когда происходит нажатие на кнопку снова вызвается эта-же функция, которая заново всё должна перезаписывать, но этого не происходит, есть другие варианты? У меня догадок нет... Своего рода реактивость DOM
P.S. Кстати, каждый раз, при парсинге JSON вылетает ошибка: Uncaught SyntaxError: Unexpected end of JSON input
at JSON.parse ()
at XMLHttpRequest.xhr.onreadystatechange (common.js:80)
, хотя я проверял несколько раз, JSON приходит нормальный, парсится он тоже нормально, но ошибку выдает, странное поведение JS
  • Вопрос задан
  • 169 просмотров
Решения вопроса 1
MayorPlay
@MayorPlay Автор вопроса
!developer
Проблема была решена, сделал событие клика не на каждый элемент по отдельности, а на объект window и проверял на нужный элемент, теперь все события нужные распространяются и на динамически добавленные и на динамически измененные элементы.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы