> sorry for my english)
In a nutshell: need replace querySelector with querySelectorAll and keep the functionality in slider (const sliderItems)
Hi all, I have a slider and it seems to work fine, but only if I use querySelector. For further manipulation - I need to select all elements, (querySelectorAll). It seemed to be no big deal, but the slider stops working when I use querySelectorAll. I'm asking for help, because I have no idea how to fix it, without loss of functionality :)
JavaScript:
const slider = document.querySelectorAll('.slider'),
sliderItems = document.querySelector('.slider__items'),
prev = document.querySelectorAll('.prev'),
next = document.querySelectorAll('.next');
function slide(wrapper, items, prev, next) {
let posInitial,
slides = items.querySelectorAll('.slider__items *'),
slidesLength = slides.length,
slideSize = items.querySelectorAll('.slider__items *')[0].offsetWidth,
firstSlide = slides[0],
lastSlide = slides[slidesLength - 1],
cloneFirst = firstSlide.cloneNode(true),
cloneLast = lastSlide.cloneNode(true),
index = 0,
allowShift = true;
//Set offset to first slide
const slideWidth = window.getComputedStyle(firstSlide);
console.log(slideWidth.width);
items.style.left = `-${slideWidth.width}`;
// Clone first and last slide
items.appendChild(cloneFirst);
items.insertBefore(cloneLast, firstSlide);
wrapper.forEach(item => {
item.classList.add('loaded');
});
// Click events
prev.forEach(item => {
item.addEventListener('click', function () { shiftSlide(-1) });
})
next.forEach(item => {
item.addEventListener('click', function () { shiftSlide(1) });
})
// Transition events
items.addEventListener('transitionend', checkIndex);
function shiftSlide(dir, action) {
items.classList.add('shifting');
if (allowShift) {
if (!action) { posInitial = items.offsetLeft; }
if (dir == 1) {
items.style.left = (posInitial - slideSize) + "px";
index++;
} else if (dir == -1) {
items.style.left = (posInitial + slideSize) + "px";
index--;
}
};
allowShift = false;
}
function checkIndex (){
items.classList.remove('shifting');
if (index == -1) {
items.style.left = -(slidesLength * slideSize) + "px";
index = slidesLength - 1;
}
if (index == slidesLength) {
items.style.left = -(1 * slideSize) + "px";
index = 0;
}
allowShift = true;
}
}
slide(slider, sliderItems, prev, next);
HTML:
<div class="slider">
<div class="slider__wrapper">
<div class="slider__items">
<span class="slider__slide">Slide 1</span>
<span class="slider__slide">Slide 2</span>
<span class="slider__slide">Slide 3</span>
<span class="slider__slide">Slide 4</span>
<span class="slider__slide">Slide 5</span>
<span class="vertical slider__slide vertical">Slide 6</span>
</div>
</div>
<a id="prev" class="control prev"></a>
<a id="next" class="control next"></a>
</div>
CSS:
.slider {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
box-shadow: 3px 3px 10px rgba(0, 0, 0, 0.2);
}
.slider__wrapper {
position: relative;
width: 600px;
height: 400px;
overflow: hidden;
z-index: 1;
}
.slider__items {
display: flex;
position: absolute;
}
.slider__items.shifting {
transition: left 0.2s ease-out;
}
.slider__slide {
display: flex;
justify-content: center;
align-items: center;
width: 600px;
height: 400px;
cursor: pointer;
transition: all 1s;
background: #FFCF47;
border-radius: 2px;
}
.slider.loaded .slider__slide:nth-child(2),
.slider.loaded .slider__slide:nth-child(7) {
background: #FFCF47;
}
.slider.loaded .slider__slide:nth-child(1),
.slider.loaded .slider__slide:nth-child(6) {
background: #7ADCEF;
}
.slider.loaded .slider__slide:nth-child(3) {
background: #3CFF96;
}
.slider.loaded .slider__slide:nth-child(4) {
background: #a78df5;
}
.slider.loaded .slider__slide:nth-child(5) {
background: #ff8686;
}
.control {
position: absolute;
top: 50%;
width: 50px;
height: 50px;
background: #fff;
border-radius: 50px;
margin-top: -20px;
box-shadow: 1px 1px 10px rgba(0, 0, 0, 0.3);
z-index: 2;
}
.prev,
.next {
background-size: 22px;
background-position: center;
background-repeat: no-repeat;
cursor: pointer;
}
.prev {
background-image: url(https://cdn0.iconfinder.com/data/icons/navigation-set-arrows-part-one/32/ChevronLeft-512.png);
left: -20px;
}
.next {
background-image: url(https://cdn0.iconfinder.com/data/icons/navigation-set-arrows-part-one/32/ChevronRight-512.png);
right: -20px;
}
.prev:active,
.next:active {
transform: scale(0.8);
}
I tried to replace querySelector with querySelectorAll myself, but then I got a bunch of errors and the script didn't work :)
Why do you need to use querySelectorAll()?
<div class="slider__items">
There are only one of these elements in your code, so querySelector() seems appropriate.
If you want to use querySelectorAll, remember that it returns a NodeList. (Like an array)
Change your last line like this to access the first(and only) element of the array.
slide(slider, sliderItems[0], prev, next);