网站打字机效果中传入构造函数的条件函数无法调用求助
解决Typewriter实例中condition函数调用报错的问题
首先,我们来拆解你遇到的矛盾问题:明明typeof(this.condition)返回function,但调用this.condition()时却提示“不是函数”。结合你的代码来看,这大概率是边界情况未处理或隐性的this指向问题导致的,另外你的代码还存在打字完成后无限循环的小问题,我们一起修复。
问题根源分析
- 未处理参数缺失场景:如果在某些使用场景下忘记传入
condition函数,this.condition会变成undefined,调用时自然触发“不是函数”的错误——哪怕你现在传入了参数,也应该加默认值避免这类边界错误。 - this指向的潜在风险:虽然你在
setTimeout里用箭头函数保留了实例的this指向,但如果condition是某个对象的方法,调用时会因为自身this丢失导致异常(你的示例里是独立函数,这个问题不明显,但提前处理更稳妥)。 - 无限循环浪费性能:当前代码会一直重复执行
setTimeout,即使所有字符都已经打印完成,没必要持续消耗资源。
修改后的完整代码
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> </head> <body> <h1>This should be typed in a Typewriter effect</h1> <script> const Typewriter = function(element, wordsToPrint, condition = () => true) { this.element = element; this.wordsToPrint = wordsToPrint; // 绑定condition的this到实例,避免函数自身this丢失 this.condition = condition.bind(this); this.currValue = ''; this.type(); } // 打字效果核心方法 Typewriter.prototype.type = function() { // 打印完成后终止循环 if (this.currValue === this.wordsToPrint) { return; } // 条件满足时追加字符 if (this.condition()) { this.currValue = this.wordsToPrint.substring(0, this.currValue.length + 1); this.element.innerHTML = this.currValue; } setTimeout(() => this.type(), 80); } // DOM加载完成后初始化 document.addEventListener("DOMContentLoaded", init); function init() { const someElement = { element: document.querySelector("h1"), content: document.querySelector("h1").innerHTML } // 清空原始文本准备打字效果 someElement.element.innerHTML = ''; const conditionFunc = function() { return true; } // 创建打字机实例 new Typewriter(someElement.element, someElement.content, conditionFunc); } </script> </body> </html>
关键修改说明
- 添加condition默认值:构造函数参数里设置
condition = () => true,确保即使未传入条件函数,打字效果也能默认执行。 - 绑定condition的this:用
condition.bind(this)把条件函数的this绑定到Typewriter实例,避免如果condition是对象方法时的this丢失问题。 - 添加终止条件:当
currValue和目标文本完全一致时,直接返回停止后续的setTimeout调用,避免无限循环。
额外扩展建议
如果你需要动态条件(比如滚动到元素可见时才触发打字),可以把condition设计成动态检查的函数,比如:
// 示例:仅当元素进入视口才执行打字效果 const conditionFunc = function() { const rect = this.element.getBoundingClientRect(); return rect.top < window.innerHeight && rect.bottom > 0; }
因为我们已经绑定了this,所以可以直接在condition函数里通过this.element访问目标元素。
内容的提问来源于stack exchange,提问作者Manu
相关产品推荐
相关产品推荐

