So I am trying to make a carousel in Javascript and Uncaught TypeError: Cannot set property 'className' of undefined is showing in my console for setClasses and at initCarousel. I am not sure how to fix it, this is the javascript I have written already. Any and all help would be appreciated, muchas gracias
!(function(d){
var itemClassName = "carousel__photo";
items = d.getElementsByClassName(itemClassName),
totalItems = items.length,
activeSlides = 4;
slideLeft = 0,
slideRight = slideLeft + activeSlides - 1;
//set previous, active and next images (minimum of 3 images)
function setClasses(previous, firstActive, next) {
items[previous].className = itemClassName + " prev";
items[firstActive].className = itemClassName + " active";
for (let i = 1; i < activeSlides; i++) {
items[slideLeft + i].className = itemClassName + " active";
}
items[next].className = itemClassName + " next";
}
//set event listeners
function setEventListeners() {
var next = d.getElementsByClassName('carousel__button--next')[0],
prev = d.getElementsByClassName('carousel__button--prev')[0];
next.addEventListener('click', moveNext);
prev.addEventListener('click', movePrev);
}
//next navigation handler
function moveNext() {
//if right-most slide has reached end of carousel, reset carousel to start
if (slideRight == (totalItems-1)) {
slideLeft = 0;
//else right-shift carousel based on number of slides remaining until end
} else {
var slidesRemaining = totalItems - slideRight - 1;
slideLeft = (slidesRemaining >= activeSlides) ? slideLeft + activeSlides : slideLeft + slidesRemaining;
}
moveCarouselTo(slideLeft);
}
//previous navigation handler
function movePrev() {
//if left-most slide has reached start of carousel, reset carousel to end
if (slideLeft === 0) {
slideLeft = (totalItems - activeSlides);
//left-shift carousel based on number of slides remaining until start
} else {
slideLeft = (slideLeft >= activeSlides) ? slideLeft - activeSlides : 0;
}
moveCarouselTo(slideLeft);
}
function moveCarouselTo(slideLeft) {
slideRight = slideLeft + activeSlides - 1;
//previous slide is always 1 slide before left-most slide, unless left-most slide is at start
var newPrevious = (slideLeft != 0) ? slideLeft - 1 : totalItems - 1;
//next slide is always 1 slide after right-most slide, unless right-most slide is at end
var newNext = (slideRight != totalItems - 1) ? slideRight + 1 : 0;
//reset images to default classes
for (let item of items) {
item.className = itemClassName;
}
//set new previous, active and next images
setClasses(newPrevious, slideLeft, newNext);
}
function initCarousel() {
setClasses(totalItems - 1, 0, activeSlides);
setEventListeners();
}
initCarousel();
}(document));
You are getting the exception because some variable is undefined, so let's explore and find it:
TypeError: Cannot set property 'className' of undefined
for this exception you need to look what line it's happening. Based on your comment "...for setClasses and at initCarousel" it looks like it happens in this line:
function setClasses(previous, firstActive, next) {
items[previous].className = itemClassName + " prev";
// .............^ your exception
}
And this looks like you are accessing a invalid index in your array, most probably your variable items is empty. This example bellow will show this exception too, with a little different message, because the exception is catched by the hosting, but in the devtools console is the same:
var array = []; // empty
array[0].className = "foo";
You need investigate why items is empty, if not empty you need to figure out why previous gets a invalid index in items, you can use the debugger of chrome devtools (F12) and put a breakpoint in this line.
There is a chance that items is empty because You are running your code before the page load the DOM or before the carousel loads itself, so you can try to use the load event:
// you can try with "DOMContentLoaded" too
document.addEventListener("load", function() {
// your code goes here
});
or if the images of carousel loads with an API you can use some event of that API to ensure that your code runs after the elements are present in DOM.