debugging 未捕获的TypeError:无法设置js中未定义的属性'className'

9njqaruj  于 2022-12-13  发布在  其他
关注(0)|答案(1)|浏览(154)

所以我尝试用Javascript和未捕获的TypeError制作一个carousel:无法设置未定义的属性'className'显示在我的控制台中的setClasses和initCarousel。我不知道如何修复它,这是我已经写好的javascript。
!(函数(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();

}(文件));

evrscar2

evrscar21#

因为某个变量未定义,所以会出现异常,让我们来探索并找到它:
TypeError:无法设定未定义的属性'className'
对于这个异常,你需要查看它发生在哪一行。根据你的注解“... forsetClassesand at initCarousel”,它看起来像是发生在这一行:

function setClasses(previous, firstActive, next) {
    items[previous].className = itemClassName + " prev";
    // .............^ your exception
}

这看起来像是你正在访问数组中的一个无效索引,最有可能的是你的变量items是空的。下面的这个例子也会显示这个异常,消息有点不同,因为这个异常是由宿主捕获的,但是在devtools控制台中是一样的:

var array = []; // empty
array[0].className = "foo";

那么,如何解决这个问题呢?

你需要调查为什么项目是空的,如果不是空的,你需要找出为什么previous在项目中得到一个无效的索引,你可以使用chrome devtools的调试器(F12),并在这一行中放置一个断点。
items有可能是空的,因为您在页面加载DOM之前或carousel加载自身之前运行代码,所以您可以尝试使用load事件:

// you can try with "DOMContentLoaded" too
document.addEventListener("load", function() {
   // your code goes here
});

或者如果carousel的图像通过API加载,则可以使用该API的某个事件来确保代码在元素出现在DOM中之后运行。

相关问题