Jakiś czas temu popełniłem podobny projekt. Na podstawie Waszych uwag stwierdziłem, że:
- kod był rakotwórczy
- kod był "uszyty" pod konkretny zestaw znaczników HTML, czyli nieuniwersalny
Mając już troszkę więcej doświadczenia i wyczucia napisałem ten kod jeszcze raz. Póki co prezentuję wersję funkcyjną, może niebawem zrobię wersję OOP. W każdym razie tak starałem się pisać kod, by był uniwersalny i pozwalał dodać coś w przyszłości. Czyli teraz nie ma znaczenia, ile zdjęć jest na stronie. Dodanie nowej galerii również nie wymaga ingerencji w kod. Za każdym razem skrypt działa tak samo. Jedyne miejsce gdzie coś ewentualnie będzie wymagało zmiany, to nazwy class i id znaczników HTML, które chwyciłem na początku kodu jako const.
Nazwy znaczników HTML pomińcie, celowo użyłem tych z poprzedniej wersji.
Kod HTML:
<body>
<p>Sypialnia</p>
<div class = "galeria">
<img class = "mini" src = sypialnia1.jpg>
<img class = "mini" src = sypialnia2.jpg>
<img class = "mini" src = sypialnia3.jpg>
</div>
<p>Kuchnia</p>
<div class = "galeria">
<img class = "mini" src = kuchnia1.jpg>
<img class = "mini" src = kuchnia2.jpg>
<img class = "mini" src = kuchnia3.jpg>
</div>
<div id = "modal_okno">
<span id = "modal_zamknij">×</span>
<span id = "modal_next">❯</span>
<img id = "modal_obraz" src = (1).jpg>
<span id = "modal_prev">❮</span>
<span id = "modal_numer"></span>
</div>
</body>
Kod JS:
const pictureClassName = "mini";
const gallery = document.getElementsByClassName("galeria");
const windowModal = document.getElementById("modal_okno");
const pictureModal = document.getElementById("modal_obraz");
const buttonClose = document.getElementById("modal_zamknij");
const buttonNext = document.getElementById("modal_next");
const buttonPrev = document.getElementById("modal_prev");
const pictureId = document.getElementById("modal_numer");
buttonClose.addEventListener('click', hideModal);
buttonNext.addEventListener('click', (e) => nextPicture(e));
buttonPrev.addEventListener('click', (e) => previousPicture(e));
for (let i = 0; i < gallery.length; i++)
{
gallery[i].addEventListener('click', (e) =>
{
if (e.target.className == pictureClassName)
{
let pictureName = getName(e);
showModal();
putPicture(pictureName);
showPictureNumber(pictureName);
}
});
}
function getName(e)
{
let name = e.target.getAttribute("src");
return name;
}
function showModal()
{
windowModal.style.display = "block";
}
function hideModal()
{
windowModal.style.display = "none";
}
function putPicture(pictureName)
{
pictureModal.src = pictureName;
}
function showPictureNumber(pictureName)
{
let pictures = document.querySelectorAll('img[class~=' + pictureClassName + ']');
let pictureNumberTotal = pictures.length;
let pictureNumberShown = 0;
pictures.forEach((el, index) =>
{
if (el.getAttribute("src") == pictureName)
{
pictureNumberShown = index+1;
}
});
let pictureLabel = pictureNumberShown + "/" + pictureNumberTotal;
pictureId.textContent = pictureLabel;
}
function nextPicture(e)
{
let currentPicture = e.target.nextElementSibling.getAttribute("src");
putPicture(findNextPicture(currentPicture, "next"));
}
function previousPicture(e)
{
let currentPicture = e.target.previousElementSibling.getAttribute("src");
putPicture(findNextPicture(currentPicture, "prev"));
}
function findNextPicture(currentPicture, direction)
{
let anotherPicture = "";
let pictures = document.querySelectorAll('img[class~=' + pictureClassName + ']');
pictures.forEach((el, index) =>
{
if (el.getAttribute("src") == currentPicture)
{
switch (direction)
{
case "next":
anotherPicture = pictures[Math.min(pictures.length-1, index+1)].getAttribute("src");
break;
case "prev":
anotherPicture = pictures[Math.max(0, index-1)].getAttribute("src");
break;
}
showPictureNumber(anotherPicture);
}
});
return anotherPicture;
}
document.addEventListener('keydown', (e) =>
{
if (windowModal.style.display == "block")
{
switch (e.keyCode)
{
case 37:
putPicture(findNextPicture(pictureModal.getAttribute("src"), "prev"));
break;
case 39:
putPicture(findNextPicture(pictureModal.getAttribute("src"), "next"));
break;
}
}
});
Zastanawiam się jeszcze, czy zamiast forEach nie lepiej użyć filter. Tylko wtedy dodatkowo jeszcze trzeba przerobić obiekt na tablicę. A może jest lepszy sposób na takie przefiltrowanie listy elementów img?