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

如何用Knockout读取JSON数据并实现可控速的打字机效果

解决方案:Knockout 打字机效果实现(支持多速度控制)

核心思路

通过Knockout的可观察对象跟踪当前场景数据和正在显示的文本片段,用定时器逐字符拼接文本实现打字机效果,同时给每个场景配置专属打字速度,切换场景时自动触发对应速度的打字逻辑。


完整可运行代码

1. HTML 结构

<div class="scene">
  <img data-bind="attr: { src: currentScene().image }" alt="Scene Image">
  <span class="scene__text" data-bind="text: displayedText"></span>
  <!-- 按钮初始隐藏,打字完成后显示 -->
  <button class="scene__choice" 
          data-bind="text: choiceText, click: changeScene, visible: isTypingComplete">
  </button>
</div>

2. JavaScript 实现(Knockout ViewModel)

// 扩展场景数据,添加打字速度配置(fast/normal/slow)
var story = {
    0: {
      text: "zzzzz", 
      image: "img/gargoylep.gif",
      speed: "slow", // 慢速打字
      choices: [
        {
             choiceText: "wake them?",
             storyLink: 1
        },
      ]
    },
    1: {
      image: "img/gargoylesk.gif",
      text: "im mad",
      speed: "fast", // 快速打字
      choices: [
        {
             choiceText: "Continue",
             storyLink: 2
        }
      ]
    },
    2: {
      text: "This is normal speed text.",
      image: "img/default.gif",
      speed: "normal", // 默认速度
      choices: [
        {
             choiceText: "Start Over",
             storyLink: 0
        }
      ]
    }
};

// 打字速度映射(毫秒/字符)
var speedMap = {
  fast: 50,
  normal: 150,
  slow: 300
};

function GameViewModel() {
  var self = this;
  
  // 可观察对象:当前场景、显示文本、按钮文本、打字完成状态
  self.currentScene = ko.observable(story[0]);
  self.displayedText = ko.observable("");
  self.choiceText = ko.observable("");
  self.isTypingComplete = ko.observable(false);
  
  // 打字机核心函数
  self.typeText = function() {
    self.isTypingComplete(false);
    self.displayedText(""); // 清空之前的文本
    
    var fullText = self.currentScene().text;
    var speed = speedMap[self.currentScene().speed] || speedMap.normal;
    var charIndex = 0;
    
    var typerInterval = setInterval(function() {
      if (charIndex < fullText.length) {
        self.displayedText(self.displayedText() + fullText.charAt(charIndex));
        charIndex++;
      } else {
        clearInterval(typerInterval);
        // 打字完成后显示按钮
        self.choiceText(self.currentScene().choices[0].choiceText);
        self.isTypingComplete(true);
      }
    }, speed);
  };
  
  // 切换场景函数
  self.changeScene = function() {
    var nextSceneId = self.currentScene().choices[0].storyLink;
    self.currentScene(story[nextSceneId] || story[0]); // 找不到场景则回到初始
    self.typeText(); // 触发新场景的打字效果
  };
  
  // 初始化:启动第一个场景的打字
  self.typeText();
}

// 激活Knockout绑定
ko.applyBindings(new GameViewModel());

关键细节说明

  1. 场景数据扩展:给每个场景添加speed属性,通过speedMap映射成具体的字符间隔毫秒数,实现不同文本的速度控制。
  2. 打字逻辑实现:用setInterval逐字符拼接文本到displayedText可观察对象,Knockout会自动更新DOM显示;打字完成后才显示交互按钮,避免用户提前操作。
  3. 避免"Object Object"问题:确保绑定的是场景对象的具体属性(如currentScene().image、displayedText),而非直接绑定整个对象。
  4. 状态控制:通过isTypingComplete可观察对象控制按钮的显示/隐藏,优化交互流程。

内容的提问来源于stack exchange,提问作者CodingSkeletons

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 21:05:36