Carousel类栈溢出错误及轮播异常问题求助
轮播组件错误修复方案
核心错误分析与修复
1. 栈溢出错误(Maximum call stack size exceeded)
stopSlideShow方法内部错误地递归调用自身,导致无限循环耗尽调用栈:
stopSlideShow() { let c = this; c.stopSlideShow(); // 无限递归,直接触发栈溢出 // ... 其他错误代码 }
修复:stopSlideShow的正确功能是清除已存在的定时器,而非创建新定时器:
stopSlideShow() { if (this.timer) { clearTimeout(this.timer); this.timer = null; } }
2. 拼写错误导致的空白问题
this.slides.lenght拼写错误,应为this.slides.length,否则wrapNumber无法正确计算索引,导致找不到对应幻灯片。showSlide方法中c.slide.eq(c.currentSlide)少了s,应为c.slides.eq(c.currentSlide),否则无法选中当前幻灯片添加样式。
3. 重复调用showSlide导致的显示异常
startSlideShow方法中同时调用了c.changeSlide(true)和c.showSlide(true),但changeSlide内部已经调用了showSlide(direction),重复执行会导致幻灯片样式混乱,最终变为空白:
startSlideShow() { let c = this; c.stopSlideShow(); c.timer = setTimeout(function () { c.changeSlide(true); c.showSlide(true); // 重复调用,删除即可 c.startSlideShow(); }, c.timing); }
修复:删除重复的c.showSlide(true)调用。
4. 事件回调上下文丢失问题
原构造函数中点击圆点的回调函数this指向DOM元素而非Carousel实例,导致调用changeSlide失败,修复时使用bind绑定上下文。
完整修复后的代码
const trueNumber = function (num, max) { return num < 0 ? num + max : num; } const signNumber = function (num, max) { return num > max * 0.5 ? num % max - max : num; } const wrapNumber = function (num, max) { return trueNumber(signNumber(num, max), max); } class Carousel { constructor(o) { Object.assign(this, o); this.currentSlide = 0; this.slides = this.element.find(".slide"); this.dots = this.element.find(".control-dot"); if (this.timing) { this.startSlideShow(); } this.element.find(".control-left").on("click", () => { this.changeSlide(false); this.restartSlideShow(); }); this.element.find(".control-right").on("click", () => { this.changeSlide(true); this.restartSlideShow(); }); this.element.find(".control-dot").on("click", function () { const index = $(this).index(); this.changeSlide(index); this.restartSlideShow(); }.bind(this)); } changeSlide(direction) { this.previousSlide = this.currentSlide; if (direction === true) { this.currentSlide++; } else if (direction === false) { this.currentSlide--; } else { if (this.currentSlide === direction) { return; } this.currentSlide = direction; direction = this.currentSlide > this.previousSlide; } this.currentSlide = wrapNumber(this.currentSlide, this.slides.length); this.showSlide(direction); } showSlide(direction) { this.slides.removeClass("moving left right center"); this.slides.eq(this.previousSlide).addClass("center"); if (direction) { this.slides.eq(this.currentSlide).addClass("right"); } else { this.slides.eq(this.currentSlide).addClass("left"); } setTimeout(() => { this.dots.eq(this.currentSlide).addClass("active").siblings().removeClass("active"); this.slides.eq(this.currentSlide).removeClass("left right").addClass("center moving"); if (direction) { this.slides.eq(this.previousSlide).removeClass("center").addClass("left moving"); } else { this.slides.eq(this.previousSlide).removeClass("center").addClass("right moving"); } }, 10); } startSlideShow() { this.stopSlideShow(); this.timer = setTimeout(() => { this.changeSlide(true); this.startSlideShow(); }, this.timing); } stopSlideShow() { if (this.timer) { clearTimeout(this.timer); this.timer = null; } } restartSlideShow() { this.stopSlideShow(); if (this.timing) { this.timer = setTimeout(() => { this.startSlideShow(); }, 5000); } } }
额外优化点
- 构造函数中的事件回调使用箭头函数或
bind确保this指向Carousel实例,避免上下文丢失。 - 条件判断使用
===替代==,提升代码严谨性。
内容的提问来源于stack exchange,提问作者nataliovalles
相关产品推荐
相关产品推荐

