Как вставить дочерний элемент, который я создаю с помощью обратных кавычек?
Я изобретаю велосипед и делаю свою корзину. Для добавления в корзину товара написал это:
let popularCars = document.querySelectorAll('.popularCarSlide '); //это карточка товара, который показывается в каталоге
let cartList = []
function addCartItem (title, price, img){ // это функция, которая создаёт элемент DOM
let cartItem = `
<div class="popupCartItem">
<img src="`+ img + `" alt="" class="popupCarItemtImg">
<p class="popupCartItemName">` + title + ` </p>
<div class="popupCartPrice">
<p class="popupCartPriceNum">` + price + `</p>
<p class="popupCartPriceCredit">в кредит</p>
</div>
<svg class="popupCartItemDelete" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M2.21311 1.57107L16.3552 15.7132M2.21311 15.7132L16.3552 1.57107" stroke="#404040" stroke-width="2"
stroke-linecap="square" />
</svg>
</div>
`
return (cartItem)
}
if(popularCars.length > 0) {
let cartWraper = document.querySelector('.popupCartWraper')
for(let i = 0; popularCars.length > i ; i++) {
let carBtn = popularCars[i].querySelector('.popularSlideOstavitZayavku'),
carTitle = popularCars[i].querySelector('.popularSlideName').textContent,
carPrice = popularCars[i].querySelector('.popularSlideItemPriceText').textContent,
carImg = popularCars[i].querySelector('.popularSlideImg').getAttribute('src');
carBtn.onclick = ()=>{
cartList.push ({
title: carTitle,
price: carPrice,
img: carImg
})
for(let o = 0; cartList.length > o; o++) {
cartWraper.insertBefore(addCartItem(cartList[o].title, cartList[o].price, cartList[o].img), cartWraper.childNodes[o]) //попытка вставить элемент как дочерний
}
}
}
}
Но сталкиваюсь с ошибкой, что это не node элемент "Failed to execute 'insertBefore' on 'Node': parameter 1 is not of type 'Node'." есть ли способ сделать из подобного элемента node и/или пихнуть его как дочерний элемент в контейнер?
Ответы (3 шт):
Используйте insertAdjacentHTML
У которого есть 4-ре позиции для вставки:
'beforebegin': до самого element (до открывающего тега).
'afterbegin': сразу после открывающего тега element (перед первым потомком).
'beforeend': сразу перед закрывающим тегом element (после последнего потомка).
'afterend': после element (после закрывающего тега).
Соответственно применять этот метод надо будет уже к cartWraper.childNodes[o]
Вы можете немного модифицировать код функции, что бы он возвращал нужный вам тип данных, а именно Node
Создаете элемент div с помощью document.createElement(), в него добавляете оставшиеся элементы с помощью innerHTML и возвращаете уже элемент с типом HTMLDivElement(DOM Node)
function addCartItem(title, price, img) {
const cartItem = document.createElement('div');
cartItem.classList.add('popupCartItem');
cartItem.innerHTML = `<img src="${img}" alt="" class="popupCarItemtImg">
<p class="popupCartItemName">${title}</p>
<div class="popupCartPrice">
<p class="popupCartPriceNum">${price}</p>
<p class="popupCartPriceCredit">в кредит</p>
</div>
<svg class="popupCartItemDelete" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M2.21311 1.57107L16.3552 15.7132M2.21311 15.7132L16.3552 1.57107" stroke="#404040" stroke-width="2"
stroke-linecap="square" />
</svg>`;
return cartItem;
}
Да, чтобы вставить HTML-строку как дочерний элемент в контейнер, нужно сначала создать DOM-элемент из этой HTML-строки. Это можно сделать, используя метод createElement и insertAdjacentHTML.
В вашем случае, вместо возвращения HTML-строки из функции addCartItem, попробуйте создать DOM-элемент с помощью createElement, заполнить его содержимым с помощью insertAdjacentHTML и затем вставить этот элемент в контейнер.
Примерно так:
function addCartItem (title, price, img){
let cartItem = document.createElement('div');
cartItem.classList.add('popupCartItem');
cartItem.insertAdjacentHTML('beforeend', `
<img src="${img}" alt="" class="popupCarItemtImg">
<p class="popupCartItemName">${title}</p>
<div class="popupCartPrice">
<p class="popupCartPriceNum">${price}</p>
<p class="popupCartPriceCredit">в кредит</p>
</div>
<svg class="popupCartItemDelete" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M2.21311 1.57107L16.3552 15.7132M2.21311 15.7132L16.3552 1.57107" stroke="#404040" stroke-width="2" stroke-linecap="square" />
</svg>
`);
return cartItem;
}
if(popularCars.length > 0) {
let cartWrapper = document.querySelector('.popupCartWraper');
for(let i = 0; i < popularCars.length; i++) {
let carBtn = popularCars[i].querySelector('.popularSlideOstavitZayavku'),
carTitle = popularCars[i].querySelector('.popularSlideName').textContent,
carPrice = popularCars[i].querySelector('.popularSlideItemPriceText').textContent,
carImg = popularCars[i].querySelector('.popularSlideImg').getAttribute('src');
carBtn.onclick = () => {
cartList.push({
title: carTitle,
price: carPrice,
img: carImg
});
cartWrapper.innerHTML = ''; // очищаем контейнер от предыдущих элементов
cartList.forEach((cartItem) => {
cartWrapper.appendChild(addCartItem(cartItem.title, cartItem.price, cartItem.img));
});
}
}
}
Таким образом HTML-элемент будет создан из строки cartItem с помощью createElement и добавлен в контейнер с помощью метода appendChild.