Как менять картинки при клике на кнопку?
Нужно, при клике на цвет, менять картинку. Но проблема в том что таких блоков может быть на странице много, а все применяется только к первому. Подскажите пожалуйста, как сделать так что-бы у каждого блока менялась своя картинка?
document.body.addEventListener('click', e => {
if (!e.target.matches('button')) return
document.querySelector('.pic img').src = e.target.dataset.src
document.querySelectorAll('button').forEach(btn => btn.classList.remove('active'))
e.target.classList.add('active')
})
.pic {
display: inline-block;
}
button {
padding: 1em;
}
button.active {
background: tomato;
}
<div class="content">
<div class="pic">
<img src="https://image.coolblue.nl/422x390/products/1216241">
</div>
<button data-src="https://image.coolblue.nl/422x390/products/1216241" class="active">
Blue
</button>
<button data-src="https://image.coolblue.nl/422x390/products/1214824">
Black
</button>
<div>
<div class="content">
<div class="pic">
<img src="https://image.coolblue.nl/422x390/products/1216241">
</div>
<button data-src="https://image.coolblue.nl/422x390/products/1216241" class="active">
Blue
</button>
<button data-src="https://image.coolblue.nl/422x390/products/1214824">
Black
</button>
<div>
Ответы (2 шт):
На вскидку 2 варианта.
Первый - искать картинку не в document, а в родителе нашего target.
e.target.parentElement.querySelector('.pic img').src = e.target.dataset.src
Второй, на мой взгляд более универсальный, - добавить к блокам .content ID товара (типа id="item-1"), добавить в кнопики data-itemid, в котором будет содержаться ID товара, картинку которого нужно изменить. В таком случае смена картинки будет делаться как-то так:
let pic = document.querySelector('#' + e.target.dataset.itemid + ' .pic img')
pic.src = e.target.dataset.src
Второй вариант более универсальный, т.к. не так сильно привязан к структуре HTML. Поэтому рабочий пример ниже именно с ним.
PS. Не забывайте корректно закывать HTML блоки. В вашем примере в коце блоков .content у вместо закрывающего тега </div>, открывающий - <div>
document.body.addEventListener('click', e => {
if (!e.target.matches('button')) return
let pic = document.querySelector('#' + e.target.dataset.itemid + ' .pic img')
pic.src = e.target.dataset.src
document.querySelectorAll('#' + e.target.dataset.itemid + ' button').forEach(btn => btn.classList.remove('active'))
e.target.classList.add('active')
})
.pic {
display: inline-block;
}
button {
padding: 1em;
}
button.active {
background: tomato;
}
<div class="content" id="item-1">
<div class="pic">
<img src="https://image.coolblue.nl/422x390/products/1216241">
</div>
<button data-src="https://image.coolblue.nl/422x390/products/1216241" class="active" data-itemid="item-1">
Blue
</button>
<button data-src="https://image.coolblue.nl/422x390/products/1214824" data-itemid="item-1">
Black
</button>
</div>
<div class="content" id="item-2">
<div class="pic">
<img src="https://image.coolblue.nl/422x390/products/1216241">
</div>
<button data-src="https://image.coolblue.nl/422x390/products/1216241" class="active" data-itemid="item-2">
Blue
</button>
<button data-src="https://image.coolblue.nl/422x390/products/1214824" data-itemid="item-2">
Black
</button>
</div>
Я бы предложил такой вариант. В нем вы слушаем любые клики по document (в идеале, нужно повесить слушатель на контейнер, который оборачивает данные блоки), проверяем, что элемент на котором кликнули - кнопка и получаем нашу обертку в виде .content, изображение и активную кнопку. Убираем у активной кнопки класс active, даем его для нажатой кнопки и устанавливаем для image src из атрибута кнопки - data-src.
document.addEventListener("click", ({target}) =>
{
if (target.tagName !== "BUTTON")
{
return;
}
const wrapper = target.closest(".content");
if (wrapper === null)
{
return;
}
const image = wrapper.querySelector(".pic img");
const activeButton = wrapper.querySelector("button.active");
if (image === null || activeButton === null)
{
return;
}
activeButton.classList.remove("active");
const button = target;
button.classList.add("active");
image.src = button.dataset.src;
});
.pic {
display: inline-block;
}
button {
padding: 1em;
}
button.active {
background: tomato;
}
<div class="content">
<div class="pic">
<img src="https://image.coolblue.nl/422x390/products/1216241">
</div>
<button data-src="https://image.coolblue.nl/422x390/products/1216241" class="active">
Blue
</button>
<button data-src="https://image.coolblue.nl/422x390/products/1214824">
Black
</button>
</div>
<div class="content">
<div class="pic">
<img src="https://image.coolblue.nl/422x390/products/1216241">
</div>
<button data-src="https://image.coolblue.nl/422x390/products/1216241" class="active">
Blue
</button>
<button data-src="https://image.coolblue.nl/422x390/products/1214824">
Black
</button>
</div>