Я создала галерею с изображениями.Мне необходимо: 1) динамически создать элементы галереи по указанному шаблону; 2)При клике по элементу галереи должно открываться модальное окно с полноразмерным изображением. Обязательно использовать делегирование событий и слушай клики на элементе ul.gallery; 3)Модальное окно должно закрываться по клику на кнопку button[data-action="close-modal"], по клику на div.overlay или по нажатию ESC. Разметка элемента галереи должна быть:
<li class="gallery__item">
<a
class="gallery__link"
href="https://cdn.pixabay.com/photo/2010/12/13/10/13/tulips-2546_1280.jpg"
>
<img
class="gallery__image"
src="https://cdn.pixabay.com/photo/2010/12/13/10/13/tulips-2546__340.jpg"
data-source="https://cdn.pixabay.com/photo/2010/12/13/10/13/tulips-2546_1280.jpg"
alt="Tulips"
/>
<span class="gallery__icon">
<i class="material-icons">zoom_out_map</i>
</span>
</a>
</li>
Ссылка на оригинальное изображение должна храниться в data-атрибуте source на элементе img, и указываться в href ссылки. Вот мой код что у меня получилось:
'use strict';
const images = [
{
preview:
'https://cdn.pixabay.com/photo/2019/05/14/16/43/hokkaido-4202825__340.jpg',
original:
'https://cdn.pixabay.com/photo/2019/05/14/16/43/hokkaido-4202825_1280.jpg',
description: 'Hokkaido Flower',
},
{
preview:
'https://cdn.pixabay.com/photo/2019/05/14/22/05/container-4203677__340.jpg',
original:
'https://cdn.pixabay.com/photo/2019/05/14/22/05/container-4203677_1280.jpg',
description: 'Container Haulage Freight',
},
{
preview:
'https://cdn.pixabay.com/photo/2019/05/16/09/47/view-4206785__340.jpg',
original:
'https://cdn.pixabay.com/photo/2019/05/16/09/47/view-4206785_1280.jpg',
description: 'Aerial Beach View',
},
];
const menu = document.querySelector('ul.gallery');
menu.classList.add('gallery__link');
const markUp = createImages(images);
menu.insertAdjacentHTML('afterbegin', markUp);
function createImages(images) {
return images.reduce((acc, image) => (acc += createMarkup(image)), ' ');
}
function createMarkup({ preview, original, description }) {
const itemList = `<li><img src='${(preview,
original)}' alt='${description}'></li>`;
return itemList;
}
html {
box-sizing: border-box;
}
*,
*::before,
*::after {
box-sizing: inherit;
}
body {
margin: 0;
font-family: sans-serif;
background-color: #fff;
color: #212121;
}
.gallery {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
grid-gap: 16px;
max-width: 1440px;
padding: 0;
margin: 0;
list-style: none;
margin-left: auto;
margin-right: auto;
}
.gallery__item {
position: relative;
box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.2),
0px 1px 1px 0px rgba(0, 0, 0, 0.14), 0px 2px 1px -1px rgba(0, 0, 0, 0.12);
}
.gallery__image {
display: block;
height: 100%;
width: 100%;
object-fit: cover;
}
.gallery__link {
display: block;
text-decoration: none;
height: 100%;
}
.gallery__icon {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
display: flex;
align-items: center;
justify-content: center;
width: 56px;
height: 56px;
color: #fff;
cursor: pointer;
transition: opacity 200ms linear;
opacity: 0;
pointer-events: none;
}
.gallery__icon i {
font-size: 48px;
}
.gallery__item:hover .gallery__icon {
opacity: 1;
}
.gallery__image {
transition: transform 200ms ease-in-out;
}
.gallery__image:hover {
transform: scale(1.03);
}
/* Lightbox */
.lightbox {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
opacity: 0;
pointer-events: none;
transition: opacity 200ms linear;
}
.lightbox.is-open {
opacity: 1;
pointer-events: initial;
}
.lightbox__overlay {
position: absolute;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background-color: rgba(0, 0, 0, 0.8);
}
.lightbox__content {
position: absolute;
top: 0;
left: 0;
height: 100vh;
width: 100vw;
display: flex;
align-items: center;
justify-content: center;
transform: scale(0.9);
transition: transform 200ms ease-in-out;
}
.lightbox___image {
width: auto;
height: auto;
max-height: 100vh;
max-width: 100vw;
}
.lightbox.is-open .lightbox__content {
transform: scale(1);
}
.lightbox__button {
position: absolute;
top: 8px;
right: 8px;
display: flex;
align-items: center;
justify-content: center;
width: 48px;
height: 48px;
padding: 0;
margin: 0;
border: none;
border-radius: 50%;
background-color: transparent;
color: #fff;
cursor: pointer;
transition: background-color 200ms ease-in-out;
outline: none;
}
.lightbox__button:hover,
.lightbox__button:focus {
background-color: rgba(0, 0, 0, 0.5);
}
.lightbox__button i {
font-size: 36px;
}
<ul class="gallery"></ul>
<div class="lightbox is-open">
<div class="lightbox__overlay"></div>
<div class="lightbox__content">
<img class="lightbox___image " src="" alt="" />
</div>
<button
type="button"
class="lightbox__button"
data-action="close-lightbox"
>
<i class="material-icons">close</i>
</button>
</div>
const images = [
{
preview:
'https://cdn.pixabay.com/photo/2019/05/14/16/43/hokkaido-4202825__340.jpg',
original:
'https://cdn.pixabay.com/photo/2019/05/14/16/43/hokkaido-4202825_1280.jpg',
description: 'Hokkaido Flower',
},
{
preview:
'https://cdn.pixabay.com/photo/2019/05/14/22/05/container-4203677__340.jpg',
original:
'https://cdn.pixabay.com/photo/2019/05/14/22/05/container-4203677_1280.jpg',
description: 'Container Haulage Freight',
},
{
preview:
'https://cdn.pixabay.com/photo/2019/05/16/09/47/view-4206785__340.jpg',
original:
'https://cdn.pixabay.com/photo/2019/05/16/09/47/view-4206785_1280.jpg',
description: 'Aerial Beach View',
},];
const refs = {
galleryList: document.querySelector('ul.gallery'),
lightbox: document.querySelector('.lightbox'),
btn: document.querySelector('[data-action="close-lightbox"]')
};
const createImage = (item, parent) => {
const { preview, original, description } = item;
const img = document.createElement('img');
img.classList.add('gallery__image');
img.dataset.source = original;
img.src = preview;
img.alt = description;
parent.appendChild(img);
};
const createLink = (item, parent) => {
const { original } = item;
const a = document.createElement('a');
a.classList.add('gallery__link');
a.href = original;
createImage(item, a);
parent.appendChild(a);
};
const createItem = (item) => {
const li = document.createElement('li');
li.classList.add('gallery__item');
createLink(item, li);
return li;
};
const renderListItems = (arr) => {
const items = arr.map( (item) => createItem(item));
refs.galleryList.append(...items);
};
renderListItems(images);
function onClickHandler(e) {
e.preventDefault();
if(e.target.nodeName === 'IMG') {
refs.lightbox.classList.add('is-open');
refs.lightbox.querySelector('.lightbox__image').src = e.target.src;
refs.lightbox.querySelector('.lightbox__image').alt = e.target.alt;
}
}
function onCloseHandler(e) {
if(e.target.nodeName === "I" || e.target.nodeName === "BUTTON") {
refs.lightbox.classList.remove('is-open');
}
}
refs.galleryList.addEventListener('click', onClickHandler);
refs.btn.addEventListener('click', onCloseHandler);
html {
box-sizing: border-box;
}
*,
*::before,
*::after {
box-sizing: inherit;
}
body {
margin: 0;
font-family: sans-serif;
background-color: #fff;
color: #212121;
}
.gallery {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
grid-gap: 16px;
max-width: 1440px;
padding: 0;
margin: 0;
list-style: none;
margin-left: auto;
margin-right: auto;
}
.gallery__item {
position: relative;
box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.2),
0px 1px 1px 0px rgba(0, 0, 0, 0.14), 0px 2px 1px -1px rgba(0, 0, 0, 0.12);
}
.gallery__image {
display: block;
height: 100%;
width: 100%;
object-fit: cover;
}
.gallery__link {
display: block;
text-decoration: none;
height: 100%;
}
.gallery__icon {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
display: flex;
align-items: center;
justify-content: center;
width: 56px;
height: 56px;
color: #fff;
cursor: pointer;
transition: opacity 200ms linear;
opacity: 0;
pointer-events: none;
}
.gallery__icon i {
font-size: 48px;
}
.gallery__item:hover .gallery__icon {
opacity: 1;
}
.gallery__image {
transition: transform 200ms ease-in-out;
}
.gallery__image:hover {
transform: scale(1.03);
}
/* Lightbox */
.lightbox {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
opacity: 0;
pointer-events: none;
transition: opacity 200ms linear;
}
.lightbox.is-open {
opacity: 1;
pointer-events: initial;
}
.lightbox__overlay {
position: absolute;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background-color: rgba(0, 0, 0, 0.8);
}
.lightbox__content {
position: absolute;
top: 0;
left: 0;
height: 100vh;
width: 100vw;
display: flex;
align-items: center;
justify-content: center;
transform: scale(0.9);
transition: transform 200ms ease-in-out;
}
.lightbox___image {
width: auto;
height: auto;
max-height: 100vh;
max-width: 100vw;
}
.lightbox.is-open .lightbox__content {
transform: scale(1);
}
.lightbox__button {
position: absolute;
top: 8px;
right: 8px;
display: flex;
align-items: center;
justify-content: center;
width: 48px;
height: 48px;
padding: 0;
margin: 0;
border: none;
border-radius: 50%;
background-color: transparent;
color: #fff;
cursor: pointer;
transition: background-color 200ms ease-in-out;
outline: none;
}
.lightbox__button:hover,
.lightbox__button:focus {
background-color: rgba(0, 0, 0, 0.5);
}
.lightbox__button i {
font-size: 36px;
}
<ul class="gallery"></ul>
<!--
Модальное окно для полноразмерного изображения.
Для того чтобы открыть, добавь на div.lightbox CSS-класс is-open
-->
<div class="lightbox">
<div class="lightbox__overlay"></div>
<div class="lightbox__content">
<img class="lightbox___image " src="" alt="" />
</div>
<button
type="button"
class="lightbox__button"
data-action="close-lightbox"
>
<i class="material-icons">close</i>
</button>
</div>
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Такие дела: есть сервер, к которому клиент подключается по адресу
Пишу калькулятор вкладовРазмер суммы устанавливается бегунком и выводится в поле c id="summa2"
Пытаюсь изменить элемент массива по методу handleToggle, но возникает ошибка, что я делаю не так, и почему в реакте я все время должен возвращать...
При компиляции webpack получаю такую ошибку: