You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

网站打字机效果中传入构造函数的条件函数无法调用求助

解决Typewriter实例中condition函数调用报错的问题

首先,我们来拆解你遇到的矛盾问题:明明typeof(this.condition)返回function,但调用this.condition()时却提示“不是函数”。结合你的代码来看,这大概率是边界情况未处理或隐性的this指向问题导致的,另外你的代码还存在打字完成后无限循环的小问题,我们一起修复。

问题根源分析

  1. 未处理参数缺失场景:如果在某些使用场景下忘记传入condition函数,this.condition会变成undefined,调用时自然触发“不是函数”的错误——哪怕你现在传入了参数,也应该加默认值避免这类边界错误。
  2. this指向的潜在风险:虽然你在setTimeout里用箭头函数保留了实例的this指向,但如果condition是某个对象的方法,调用时会因为自身this丢失导致异常(你的示例里是独立函数,这个问题不明显,但提前处理更稳妥)。
  3. 无限循环浪费性能:当前代码会一直重复执行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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 09:09:11