Не удаляется элемент с блока
Решил создать систему корзины с использованием localStorage, и почти все работает, кроме одного: Если добавить элементы в корзину, а затем удалить, после перезагрузки они все равно отмечаются как «добавленные». Как удалить выбранное в том числе и из localStorage?
let products = document.querySelectorAll('.product-block');
let product_names = document.querySelectorAll('.product-block h5');
let favourite = document.querySelector('.favourite_elements');
let favourite_names = document.querySelectorAll('.favourite_elements h5');
let h5_storage = new Array(products.length);
let h5 = document.createElement("h5");
// Хранилище для ссылок на копируемые элементы H5
let fav_arr = new Array();
let claimed = new Array();
let id;
const compare = localStorage.getItem('claimed');
if (compare != null) {
for (var k = 0; k < compare.length; k++) {
if (Number(compare[k]) > 0) {
id = Number(compare[k]) - 1;
products[id].style.background = "orange";
favourite.insertAdjacentElement("afterbegin", product_names[id].cloneNode(true));
fav_arr.push(product_names[id].outerHTML);
claimed.push(compare[k]);
}
}
}
console.log(fav_arr);
products.forEach((product) => {
product.addEventListener("click", function() {
toggle_favourite(this); // this - ссылка на кликнутый product
});
});
function toggle_favourite(product) {
let i = [].indexOf.call(products, product);
// Номер кликнутого product среди всех остальных продуктов
if (product.style.background != "orange") {
h5_storage[i] = product_names[i].cloneNode(true);
// h5 клонируется, ссылка на клон сохраняется в хранилище под тем же номером.
product.style.background = "orange";
fav_arr.push(h5_storage[i].innerHTML);
localStorage.setItem('h5', JSON.stringify(fav_arr));
claimed.push(i + 1);
localStorage.setItem('claimed', claimed);
favourite.insertAdjacentElement("afterbegin", h5_storage[i]);
console.log(fav_arr);
} else {
product.style.background = "white";
for (var j = 0; j < fav_arr.length; j++) {
if (fav_arr[j] == product_names[i].innerHTML) {
delete fav_arr[j];
}
}
fav_arr = fav_arr.filter(function(x) {
return x !== undefined && x !== null;
});
claimed = claimed.filter(function(x) {
return x !== undefined && x !== null && x !== " ";
});
for (var s = 0; s < claimed.length; s++) {
if (claimed[s] == i + 1) {
delete claimed[s];
delete fav_arr[i];
}
}
favourite.removeChild(h5_storage[i]);
localStorage.removeItem('h5');
localStorage.setItem('h5', fav_arr);
localStorage.removeItem('claimed');
localStorage.setItem('claimed', claimed);
console.log(claimed);
}
}
for (var y = 0; y < favourite_names.length; y++) {
if (favourite_names[y].innerHTML == "undefined") {
favourite_names.parentNode.removeChild(favourite_names)
}
}
<!-- Здесь выбор объектов-->
<a href="#" class="product col-2">
<div class="product-block">
<img src="img/product.jpg">
<h5>Смартфон Samsung Galaxy A02s 32GB White</h5>
<p>59 990 тг.</p>
</div>
</a>
<a href="#" class="product col-2">
<div class="product-block">
<img src="img/product.jpg">
<h5>Смартфон Samsung Galaxy A02s 32GB White</h5>
<p>59 990 тг.</p>
</div>
</a>
<a href="#" class="product col-2">
<div class="product-block">
<img src="img/product.jpg">
<h5>Смартфон Samsung Galaxy A02s 32GB White</h5>
<p>59 990 тг.</p>
</div>
</a>
<a href="#" class="product col-2">
<div class="product-block">
<img src="img/product.jpg">
<h5>Смартфон Samsung Galaxy A02s 32GB White</h5>
<p>59 990 тг.</p>
</div>
</a>
<a href="#" class="product col-2">
<div class="product-block">
<img src="img/product.jpg">
<h5>Смартфон Samsung Galaxy A02s 32GB White</h5>
<p>59 990 тг.</p>
</div>
</a>
<a href="#" class="product col-2">
<div class="product-block">
<img src="img/product.jpg">
<h5>Смартфон Samsung Galaxy A02s 32GB White</h5>
<p>59 990 тг.</p>
</div>
</a>
<!-- Сюда добавляются заголовки-->
<div class="favourite_elements">
</div>
Ответы (1 шт):
Ошибка была тут: favourite.removeChild(h5_storage[i]); — при загрузке страницы, массив h5_storage объявляется и остается пустым, а при клике на уже оранжевые блоки (чьи h5 должны были присутствовать в массиве), выдает ошибку, т.к. h5_storage[i] — undefined.
+ h5_storage хранит DOM-объекты, его нельзя просто сохранить в localStorage через JSON.stringify. Можно было бы вместо них сохранить номера выбранных элементов, но т.к. это продукты, у них наверняка должны быть уникальные id, надежнее будет использовать их (т.к. часть продуктов может завтра пропасть или храниться в другом порядке)
claimed = claimed.filter(function(x) {
return x !== undefined && x !== null && x !== " ";
});
//...
delete claimed[i];
Элемент из массива удаляется так:
let i = claimed.indexOf(элемент);
if (i != -1) claimed.splice(i, 1);
Местами перепутали, в переменной хранится массив, строка или кто. Нужно помнить, что localStorage.getItem() всегда возвращает строку (или null, если item не существует). Если из контекста кода не очевидно, что хрантся в переменной, можно оставить комментарий где-то рядом (вплоть до полноценного примера всей структуры в комменте, если это сложный объект со вложенностями).
В коде требовалось много изменений, пришлось капитально переписать)
Здесь не работает localStorage. Рабочий пример → https://jsfiddle.net/h8sLk46d/1/
let fav_root = document.querySelector('.favourite_elements');
let fav_storage = [], init_done = false;
(function fav_storage_init() {
let fav_ids = localStorage.getItem("fav_storage");
if (!fav_ids) return;
fav_ids = JSON.parse(fav_ids);
// ["ac5f6e", "f36700"] (список id="..." ранее выбранных продуктов)
for (let i = 0; i < fav_ids.length; i++) {
let product = document.getElementById(fav_ids[i]);
if (product) fav_add(product);
// fav_add сам заполняет массив fav_storage
}
init_done = true;
// Нужна только чтобы fav_add не обновлял localStorage во время инициализации.
})();
function fav_add(product) {
let id = product.id;
fav_storage.unshift(id);
product.classList.add("fav");
let h5_node = product.querySelector("h5").cloneNode(true);
fav_root.insertAdjacentElement("afterbegin", h5_node);
if (init_done) localStorage.setItem("fav_storage", JSON.stringify(fav_storage));
}
function fav_remove(product, index) {
index = index || fav_storage.indexOf(product.id);
fav_storage.splice(index, 1);
product.classList.remove("fav");
fav_root.removeChild(fav_root.children[index]);
localStorage.setItem("fav_storage", JSON.stringify(fav_storage));
}
function fav_toggle(product) {
let index = fav_storage.indexOf(product.id);
let is_fav = (index != -1);
is_fav ? fav_remove(product, index) : fav_add(product);
}
/***/
let products = document.querySelectorAll(".product");
products.forEach(product => {
product.addEventListener("click", () => fav_toggle(product));
});
p, h5 {
margin: 4px;
}
a {
display: inline-block;
margin: 4px;
}
a.fav {
background-color: orange;
}
<a href="#" class="product col-2" id="ac5f6e">
<div class="product-block">
<h5>Смартфон Samsung Galaxy A01s 32GB White</h5>
<p>59 990 тг.</p>
</div>
</a>
<a href="#" class="product col-2" id="045acf">
<div class="product-block">
<h5>Смартфон Samsung Galaxy A02s 32GB White</h5>
<p>59 990 тг.</p>
</div>
</a>
<a href="#" class="product col-2" id="f36700">
<div class="product-block">
<h5>Смартфон Samsung Galaxy A03s 32GB White</h5>
<p>59 990 тг.</p>
</div>
</a>
<div class="favourite_elements"></div>
P.s. Тут напрашивается объект или класс с методами add / remove / toggle. Можете попробовать переписать, когда изучите class-ы в JS.