I am trying to finish a slider for a gallery of images and all I’m missing is the prev/next button functionality. Right now the prev button is working but there’s one issue. Here’s the problem, I have a gallery of images, when I click on them a popup shows up displaying the image that was clicked. However, if I click any image that isn’t the first one of the array and click the prev button, it’s gonna take me all they way back to the last image of the array, instead the prev button should take me to the image previous to the one that was clicked.
So if I have 10 images, and I click the one with index of 3 in the array and click the previous button, the popup should show the image with index of 2. Let me show you what I got so far:
const overlayString = () => `
<div class="overlay">
<button class="overlay__close-icon" id="closeOverlay">×</button>
<img src="img/prev.png" alt="Previous button" class="overlay__btn" id="overlayPrev">
<img src="img/hg-1.jpg" alt="Interior view" class="overlay__img">
<img src="img/next.png" alt="Next button" class="overlay__btn" id="overlayNext">
</div>`;
// Inject template to html structure
document.querySelector('#main').insertAdjacentHTML('beforeend', overlayString());
// Replace overlay img
const overlay = img => document.querySelector('.overlay__img').src = img.src;
// Show elements based on section
let query = document.querySelector('.gallery');
let images = 'gallery__img';
if (!query) {
query = document.querySelector('.section-gallery');
images = 'section-' + images;
}
// Nodelist elements
const imageElems = document.querySelectorAll("." + images);
let currentOverlay;
// Open overlay
query.addEventListener('click', () => {
document.querySelector('.overlay').classList.add('showOverlay');
document.querySelector('body').style.overflow = 'hidden';
// Change overlay img based on the element that was clicked.
const target = event.target;
const index = Array.prototype.indexOf.call(query.children, target);
overlay(imageElems[index]);
});
// Overlay prev and next button
document.querySelector('#overlayPrev').addEventListener('click', () => {
currentOverlay > 0 ? --currentOverlay : currentOverlay = imageElems.length - 1;
overlay(imageElems[currentOverlay])
});
I know that when I click on the prev button my code is not registering the index of the element that was clicked and that’s probably the reason of why this is it not working as I want, but I’m a stuck here, any help is greatly appreciated.
No jQuery please, I am trying to do this only with pure JS.
Nowhere, do I need to get it from somewhere?, the event.target in that function is just a reference to the child that was clicked. By using this reference I can then get the index of the child in the nodelist const index = Array.prototype.indexOf.call(query.children, target); and use that to change the overlay image dynamically.
Are you saying that I should do something like this:
query.addEventListener('click', (event) => {
// Some code here
const target = event.target
};
That’s what I see in the documentation but in this case I don’t see the need of using event as a parameter of the function since it works the exact same way with or w/o using event as a parameter.
I read your post, which takes me to my last reply, this here:
languages.addEventListener('click', () => {
const target = event.target;
const id = target.id;
const type = target.type;
if (type === 'radio') {
console.log('Radio button with id="' + id + '" was clicked');
}
});
will accomplish the same as this:
languages.addEventListener('click', event => {
const target = event.target;
const id = target.id;
const type = target.type;
if (type === 'radio') {
console.log('Radio button with id="' + id + '" was clicked');
}
});
So, why do I need to use event as a parameter for the callback function? Maybe I didn’t explain well enough in my original post or I totally misunderstood gunhoo first reply.
That is the full code, it’s a fairly small app, it’s basically a slider using some of the concepts you taught me in the other thread but this time using only vanilla JavaScript because I want to get more familiar with it.
I have a practical code pen to show you my problem:
You have 4 squares of different colors, when you click on one of them a popup will show up displaying the image of the square that was clicked, you will also have a prev button, click on it and see what happens. You have to click any square that isn’t the last one on the far right to see what my problem is.
You will have to refresh the page to get out of the popup window.
The only place to know which img user clicked is the event handler of query. And since currentOverlay is exposed as a global variable. All you need to do is attach the index to that.
Honestly, I just knew about this because of OP’s question. So, my situation is no different than yours…
Personally, I’d always stick to specifying it as a parameter because that’s what people normally would expect. Such a special treatment to callback parameter just seems odd to me although there must be a decent reason why that behavior exists.
So, as far as I’m not told the difference, I’ll stay explicit.
I really didn’t like how I sneaked in currentOverlay = index. Also, I’ve previously mentioned how dumping stuffs here and there is a bad design. So, I’ve decided to decouple Overlay related logic into one place for demonstration purpose and fun. Perhaps, you might be interested in the result: