Поиск по DOM элементам
У меня есть некий динамически генерируемый HTML, который по сути, является карточкой товара. Товаров может быть много.
Мне нужно, при клике на кнопку "Add to cart" получить innerText элемента Н2 с классом "item-name".
Подскажите, как это сделать максимально короткой записью, чтобы не городить в коде вот такой ужас?
e.target.parentElement.parentElement.lastElementChild.firstElementChild.firstElementChild.innerText
Пример кода ниже. Спасибо.
let btn_details = document.querySelector('.add');
btn_details.addEventListener('click', (e)=>{
console.log(e.target.parentElement.parentElement.lastElementChild.firstElementChild.firstElementChild.innerText)
})
li {
list-style: none;
}
<li class = 'phone-item' >
<fieldset class = "promo_marker normal">
<div class="item-wrapper">
<a href="#" class = 'details-link'><h2 class="item-name">${phone.name}</h2></a>
<a href="#" class = 'image' ><img src="${phone.imageUrl}" width = 150 height = 150 alt="phone image"></a>
<p class="description">${phone.snippet}</p>
<button class="btn_details">More details</button>
<button class="add" data-number = ${elem}>Add to cart</button>
</div>
</fieldset>
</li>
Ответы (2 шт):
let btn_details = document.querySelector('.add');
btn_details.addEventListener('click', (e) => {
console.log(e.target.closest('.item-wrapper').querySelector('.item-name').innerText)
})
li { list-style: none; }
<li class='phone-item'>
<fieldset class="promo_marker normal">
<div class="item-wrapper">
<a href="#" class='details-link'>
<h2 class="item-name">${phone.name}</h2>
</a>
<a href="#" class='image'><img src="${phone.imageUrl}" width="150px" height="150px" alt="phone image"></a>
<p class="description">${phone.snippet}</p>
<button class="btn_details">More details</button>
<button class="add" data-number="${elem}">Add to cart</button>
</div>
</fieldset>
</li>
Если карточек много, то нужно задействовать делегирование:
let btns_details = document.querySelector('.phone-items');
btns_details.addEventListener('click', (ev) => {
if (ev.target.classList.contains('add')) {
console.log(ev.target.closest('.item-wrapper').querySelector('.item-name').innerText);
}
})
li { list-style: none; }
<ul class="phone-items">
<li class='phone-item'>
<fieldset class="promo_marker normal">
<div class="item-wrapper">
<a href="#" class='details-link'><h2 class="item-name">phone_1</h2></a>
<a href="#" class='image'><img src="${phone.imageUrl}" width="150px" height="150px" alt="phone image"></a>
<p class="description">${phone.snippet}</p>
<button class="btn_details">More details</button>
<button class="add" data-number="${elem}">Add to cart</button>
</div>
</fieldset>
</li>
<li class='phone-item'>
<fieldset class="promo_marker normal">
<div class="item-wrapper">
<a href="#" class='details-link'><h2 class="item-name">phone_2</h2></a>
<a href="#" class='image'><img src="${phone.imageUrl}" width="150px" height="150px" alt="phone image"></a>
<p class="description">${phone.snippet}</p>
<button class="btn_details">More details</button>
<button class="add" data-number="${elem}">Add to cart</button>
</div>
</fieldset>
</li>
<li class='phone-item'>
<fieldset class="promo_marker normal">
<div class="item-wrapper">
<a href="#" class='details-link'><h2 class="item-name">phone_3</h2></a>
<a href="#" class='image'><img src="${phone.imageUrl}" width="150px" height="150px" alt="phone image"></a>
<p class="description">${phone.snippet}</p>
<button class="btn_details">More details</button>
<button class="add" data-number="${elem}">Add to cart</button>
</div>
</fieldset>
</li>
</ul>
В этом случае будет эффективней использовать делегирование событий. Идея в том, что если у нас есть много элементов, события на которых обрабатываются одинаково, то вместо того, чтобы назначать обработчик каждому, мы можем использовать один обработчик для их общего предка:
const btn_details = document.querySelectorAll('.phone-item')
btn_details.forEach(el => {
el.onclick = (e) => {
const target = e.target // Где был клик?
if (target.className !== 'add') return // Не на add? Тогда останавливаем скрипт.
console.log(el.querySelector('.item-name').innerText) // Показываем h2 принаджещий add, на который кликнули.
}
})
li {
list-style: none;
}
<li class="phone-item">
<fieldset class="promo_marker normal">
<div class="item-wrapper">
<a href="#" class="details-link">
<h2 class="item-name">
${phone.name}
</h2>
</a>
<a href="#" class='image'>
<img src="${phone.imageUrl}" width=150 height=150 alt="phone image">
</a>
<p class="description">${phone.snippet}</p>
<button class="btn_details">More details</button>
<button class="add" data-number=${elem}>
Add to cart
</button>
</div>
</fieldset>
</li>