JS轮播图报Uncaught TypeError:Cannot set property 'className' of undefined如何解决
错误原因
- 初始化传参越界:
initCarousel中调用setClasses时直接将第三个参数传为activeSlides=4,而DOM集合下标从0开始,若轮播项总数不足5个时,items[4]为undefined,设置className就会触发报错。 - 缺少数量校验:如果页面内
carousel__photo类的元素总数小于你设定的同时展示数量activeSlides=4,循环设置激活类时会访问到不存在的元素。 - 变量声明语法不规范:首行变量声明时
itemClassName赋值后用了分号,后续items、totalItems等变量前用逗号连接,导致这几个变量未被局部声明,变成全局变量,严格模式下也会触发异常。
修复后的完整代码
!(function(d){ // 修正变量声明语法,统一用逗号分隔 var itemClassName = "carousel__photo", items = d.getElementsByClassName(itemClassName), totalItems = items.length, activeSlides = 4, slideLeft = 0, slideRight = slideLeft + activeSlides - 1; // 基础校验,轮播项总数不足直接返回避免报错 if (totalItems < activeSlides) { console.warn('轮播项数量小于设定的同时展示数量,无法初始化') return } // 设置上一张、激活状态、下一张图片 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"; } // 设置事件监听器 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); } // 下一张导航处理函数 function moveNext() { // 若最右侧轮播项已到达轮播末尾,将轮播重置到起始位置 if (slideRight == (totalItems-1)) { slideLeft = 0; // 否则根据到末尾的剩余轮播项数量向右切换轮播 } else { var slidesRemaining = totalItems - slideRight - 1; slideLeft = (slidesRemaining >= activeSlides) ? slideLeft + activeSlides : slideLeft + slidesRemaining; } moveCarouselTo(slideLeft); } // 上一张导航处理函数 function movePrev() { // 若最左侧轮播项已到达轮播起始位置,将轮播重置到末尾位置 if (slideLeft === 0) { slideLeft = (totalItems - activeSlides); // 否则根据到起始位置的剩余轮播项数量向左切换轮播 } else { slideLeft = (slideLeft >= activeSlides) ? slideLeft - activeSlides : 0; } moveCarouselTo(slideLeft); } function moveCarouselTo(slideLeft) { slideRight = slideLeft + activeSlides - 1; // 上一张轮播项固定为最左侧轮播项前1位,若最左侧轮播项在起始位则取末尾项 var newPrevious = (slideLeft != 0) ? slideLeft - 1 : totalItems - 1; // 下一张轮播项固定为最右侧轮播项后1位,若最右侧轮播项在末尾位则取起始项 var newNext = (slideRight != totalItems - 1) ? slideRight + 1 : 0; // 将所有图片重置为默认类名 for (let item of items) { item.className = itemClassName; } // 为新的上一张、激活、下一张图片设置对应类名 setClasses(newPrevious, slideLeft, newNext); } function initCarousel() { // 修正初始next参数计算,和moveCarouselTo里的逻辑保持一致 var initNext = slideRight != totalItems - 1 ? slideRight + 1 : 0 setClasses(totalItems - 1, 0, initNext); setEventListeners(); } initCarousel(); }(document));
内容的提问来源于stack exchange,提问作者Lourdes Leiner
相关产品推荐
相关产品推荐

