Делегирование событий в изображениях
У меня есть flexbox, в котором хранятся изображения и их описание. Как мне на JS можно обыграть так, чтобы по клику на изображение (у каждого есть атрибут с уникальным номером) открывалось модальное окно, в котором показано именно то изображение, на которое я кликнул и его описание где-нибудь снизу. Модальное окно я сделал и оно успешно открывается. Почитал в интернете, что мне необходимо использовать делегирование событий, но я хочу понять сам принцип работы, и пока у меня не очень получается. Я, конечно, могу создать много модальных окон, каждое из которых будет хранить в себе изображение с уникальным id, но я уверен,что это будет лишним, т.к есть решение куда лучше с наименьшим кол-вом строк кода. Ещё было бы очень классно, если бы мне подсказали принцип работы перемотки таких изображений на подобие слайдера в попапе. Спасибо!
<div class="images__wrapper">
<div class="images__container">
<div data-id="01" class="images-container__item" onclick="showModalWindow()">
<img src="img/dormitory/main-building.jpg" class="images-container-item__img" alt="Изображение 1">
<div class="images-container-item__caption">Описание 1</div>
</div>
<div data-id="02" class="images-container__item" onclick="showModalWindow()">
<img src="img/dormitory/hall.jpeg" class="images-container-item__img" alt="Изображение 2">
<div class="images-container-item__caption">Описание 2</div>
</div>
<div data-id="03" class="images-container__item" onclick="showModalWindow()">
<img src="img/dormitory/kitchen.jpeg" class="images-container-item__img" alt="Изображение 3">
<div class="images-container-item__caption">Описание 3</div>
</div>
</div>
</div>
<div class="images__popup hide__modal__window" id="images-popup">
<div class="images__popup__container">
<div class="images-popup-cont__block">
<div class="images__popup__close" onclick="showModalWindow()">✖</div>
</div>
</div>
</div>
function showModalWindow() {
const modal = document.querySelector('#images-popup');
const bodyScroll = document.querySelector('#images-body');
if (modal.classList.contains('hide__modal__window')) {
modal.classList.remove('hide__modal__window');
modal.classList.add('show__modal__window');
} else {
modal.classList.add('hide__modal__window');
modal.classList.remove('show__modal__window');
}
if (modal.classList.contains('show__modal__window')) {
bodyScroll.classList.add('body__no-scroll');
bodyScroll.classList.remove('body__scroll');
} else {
bodyScroll.classList.remove('body__no-scroll');
bodyScroll.classList.add('body__scroll');
}
}
.images__wrapper {
width: 100%;
display: flex;
justify-content: center;
padding-top: 30px;
text-align: center;
}
.images__container {
width: 98%;
display: flex;
flex-wrap: wrap;
justify-content: center;
}
.images-container__item {
width: 350px;
height: 250px;
margin: 10px 10px;
display: flex;
justify-content: center;
align-items: center;
color: #eee;
cursor: default;
overflow: hidden;
position: relative;
}
.images-container__item img {
width: 100%;
height: 100%;
object-fit: cover;
border-radius: 20px;
}
.images-container__item img:hover {
transform: scale(1.1);
transition: .2s linear;
}
.images-container__item:hover >
.images-container-item__caption {
transition: .3s linear;
opacity: 1;
}
.images-container-item__caption {
position: absolute;
bottom: 0px;
pointer-events: none;
opacity: 0;
background-color: #641ec5;
width: 100%;
}
.images__popup {
width: 100%;
height: 100vh;
position: fixed;
top: 0;
left: 0;
z-index: 99;
display: flex;
justify-content: center;
align-items: center;
}
.show__modal__window {
display: block;
}
.hide__modal__window {
display: none;
}
.images__popup__close {
width: 40px;
height: 40px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
color: #eee;
position: absolute;
background-color: #641ec5;
padding: 0;
margin: 0;
font-size: 20px;
top: -10px;
right: -10px;
cursor: pointer;
}
.images__popup__close:hover {
background-color: #eee;
border: 2px solid #641ec5;
color: #641ec5;
transition: background-color .3s linear;
}
.images__popup__container {
width: 100%;
height: 100%;
z-index: 100;
display: flex;
justify-content: center;
align-content: center;
align-items: center;
background-color: rgba(0,0,0,0.8);
}
.images-popup-cont__block {
width: 70%;
height: 80%;
display: flex;
background-color: #eee;
position: relative;
}
const imageFinal = document.createElement("img");
imageFinal.setAttribute("src", imgSrc.src);
imageFinal.setAttribute("alt", imgSrc.alt);
const contentPopup = document.querySelector('.popup-cont-block__content');
contentPopup.appendChild(imageFinal);
contentPopup.innerHTML = imgSrc;
const contentPopup = document.querySelector('.popup-cont-block__content');
contentPopup.appendChild(imgSrc);
contentPopup.innerHTML = imgSrc;
Ответы (1 шт):
но я хочу понять сам принцип работы, и пока у меня не очень получается.
Вот смотрите, смысл в том что прослушивание вешается на общий блок, где располагаются элементы. В данном случае это images__wrapper. Далее должны сделать проверку, что если мы кликнули по изображению, тогда что-то делаем - вы хотите получить данные элементов
Пример:
const images = document.querySelector('.images__wrapper') // нашли область всех фото
images.addEventListener('click', function({
target
}) {
if (target.classList.contains('images-container-item__img')) {
let imgSrc = target.src // нашли ссылку изображения
let itemBlok = target.closest('.images-container__item') // нашли родителя
let itemTitle = itemBlok.querySelector('.images-container-item__caption').textContent // нашли описание
console.log(imgSrc)
console.log(itemTitle)
}
})
.images__wrapper {
width: 100%;
display: flex;
justify-content: center;
padding-top: 30px;
text-align: center;
}
.images__container {
width: 98%;
display: flex;
flex-wrap: wrap;
justify-content: center;
}
.images-container__item {
width: 350px;
height: 250px;
margin: 10px 10px;
display: flex;
justify-content: center;
align-items: center;
color: #eee;
cursor: default;
overflow: hidden;
position: relative;
}
.images-container__item img {
width: 100%;
height: 100%;
object-fit: cover;
border-radius: 20px;
}
.images-container__item img:hover {
transform: scale(1.1);
transition: .2s linear;
}
.images-container__item:hover>.images-container-item__caption {
transition: .3s linear;
opacity: 1;
}
.images-container-item__caption {
position: absolute;
bottom: 0px;
pointer-events: none;
opacity: 0;
background-color: #641ec5;
width: 100%;
}
.images__popup {
width: 100%;
height: 100vh;
position: fixed;
top: 0;
left: 0;
z-index: 99;
display: flex;
justify-content: center;
align-items: center;
}
.show__modal__window {
display: block;
}
.hide__modal__window {
display: none;
}
.images__popup__close {
width: 40px;
height: 40px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
color: #eee;
position: absolute;
background-color: #641ec5;
padding: 0;
margin: 0;
font-size: 20px;
top: -10px;
right: -10px;
cursor: pointer;
}
.images__popup__close:hover {
background-color: #eee;
border: 2px solid #641ec5;
color: #641ec5;
transition: background-color .3s linear;
}
.images__popup__container {
width: 100%;
height: 100%;
z-index: 100;
display: flex;
justify-content: center;
align-content: center;
align-items: center;
background-color: rgba(0, 0, 0, 0.8);
}
.images-popup-cont__block {
width: 70%;
height: 80%;
display: flex;
background-color: #eee;
position: relative;
}
<div class="images__wrapper">
<div class="images__container">
<div data-id="01" class="images-container__item">
<img src="https://images.unsplash.com/photo-1657299156791-44140a28a518?ixlib=rb-1.2.1&ixid=MnwxMjA3fDF8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1170&q=80" class="images-container-item__img" alt="Изображение 1">
<div class="images-container-item__caption">Описание 1</div>
</div>
<div data-id="02" class="images-container__item">
<img src="https://images.unsplash.com/photo-1657299156791-44140a28a518?ixlib=rb-1.2.1&ixid=MnwxMjA3fDF8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1170&q=80" class="images-container-item__img" alt="Изображение 2">
<div class="images-container-item__caption">Описание 2</div>
</div>
<div data-id="03" class="images-container__item">
<img src="https://images.unsplash.com/photo-1657299156791-44140a28a518?ixlib=rb-1.2.1&ixid=MnwxMjA3fDF8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1170&q=80" class="images-container-item__img" alt="Изображение 3">
<div class="images-container-item__caption">Описание 3</div>
</div>
</div>
</div>
Далее эти данные нужно использовать в вашем попапе. Думаю у вас должно получится.
P.S бы очень классно, если бы мне подсказали принцип работы перемотки таких изображений -- думаю пока рубеж делегирования, а потом подумаете а слайдах ))