I'm making a simple JS slider and I want to change the order of the images when I click on the prev/next button:
<div id="slider-container">
<div id="prevBtn">
<i ></i>
</div>
<div >
<div>
<img src="assets/carousel/img1.png">
</div>
<div>
<img src="assets/carousel/img2.png">
</div>
<div>
<img src="assets/carousel/img3.png">
</div>
<div>
<img src="assets/carousel/img4.png">
</div>
<div>
<img src="assets/carousel/img5.png">
</div>
</div>
<div id="nextBtn">
<i ></i>
</div>
</div>
I want to switch img2
with img1
and img1
goes to the img5
place.
JS code, added listeners to buttons:
prevBtn.addEventListener('click', () => {
if (i > 1) {
i--
} else {
i = 5;
}
});
nextBtn.addEventListener('click', () => {
if (i < 5) {
i
} else {
i = 1;
}
})
CodePudding user response:
To do what you require you can select the :first-child
/:last-child
div
elements and append()
/prepend()
them within their respective container:
const carousel = document.querySelector('.multiple-items');
document.querySelector('#prevBtn').addEventListener('click', () => {
const first = carousel.querySelector('div:first-child');
carousel.append(first);
});
document.querySelector('#nextBtn').addEventListener('click', () => {
const last = carousel.querySelector('div:last-child');
carousel.prepend(last);
});
.multiple-items > div {
display: inline-block;
width: 50px;
height: 50px;
border: 1px solid #CCC;
}
<div id="slider-container">
<div id="prevBtn">
<i >Prev</i>
</div>
<div >
<div>
<img src="assets/carousel/img1.png" alt="img1" />
</div>
<div>
<img src="assets/carousel/img2.png" alt="img2" />
</div>
<div>
<img src="assets/carousel/img3.png" alt="img3" />
</div>
<div>
<img src="assets/carousel/img4.png" alt="img4" />
</div>
<div>
<img src="assets/carousel/img5.png" alt="img5" />
</div>
</div>
<div id="nextBtn">
<i >Next</i>
</div>
</div>
CodePudding user response:
- Don't use IDs. You're limiting yourself to not being able to reuse your component inside a page. Use classes instead and have as many carousels as you desire
- Use
<button>
instead of<div>
- Use a live HTMLCollection by using Element.children
- Use .append() and .prepend() Element methods
document.querySelectorAll('.slider').forEach((elSlider) => {
const elItems = elSlider.querySelector(".slider-items");
const slides = elItems.children;
elSlider.querySelector(".slider-btn.prev").addEventListener("click", () => {
elItems.prepend(slides[slides.length - 1]);
});
elSlider.querySelector(".slider-btn.next").addEventListener("click", () => {
elItems.append(slides[0]);
});
});
.slider-items {
display: flex;
}
<div >
<div >
<div><img src="//via.placeholder.com/100x100/0bf?text=1" alt="img1"></div>
<div><img src="//via.placeholder.com/100x100/fb0?text=2" alt="img2"></div>
<div><img src="//via.placeholder.com/100x100/f0b?text=3" alt="img3"></div>
<div><img src="//via.placeholder.com/100x100/bf0?text=4" alt="img4"></div>
<div><img src="//via.placeholder.com/100x100/b0f?text=5" alt="img5"></div>
</div>
<button type="button" aria-label="previous">←</button>
<button type="button" aria-label="next">→</button>
</div>
<div >
<div >
<div><img src="//via.placeholder.com/100x100/222?text=1" alt="img1"></div>
<div><img src="//via.placeholder.com/100x100/444?text=2" alt="img2"></div>
<div><img src="//via.placeholder.com/100x100/666?text=3" alt="img3"></div>
<div><img src="//via.placeholder.com/100x100/888?text=4" alt="img4"></div>
<div><img src="//via.placeholder.com/100x100/ccc?text=5" alt="img5"></div>
</div>
<button type="button" aria-label="previous">←</button>
<button type="button" aria-label="next">→</button>
</div>
Thanks to the live HTMLCollection, with the example above you can also add slides dynamically - and the script will still work.
What the above still misses is a better UI/UX, in that in the real world things do not teleport, users are used to cognitively perceive motion through animation.