如何使用Knockout读取Json数据?



我想使用knockout创建一个Typewriter Effect,但是我不能将数据存储在表中以创建上述效果。我做了几个星期的研究,但我没有基本的知识来解决这个问题。这是我第一次问关于Stack overflow的问题。


这是基于以下代码:https://codepen.io/drewdoesdev/pen/gVrOBm

尝试这个打字机codipen: https://codepen.io/sauranerd/pen/mKKXjV?editors=1111


上面的例子没有帮助检索数据和

这里是我的变量的简短版本:

var story = {
0: {
text: "zzzzz", 
image: "img/gargoylep.gif",
choices: [
{
choiceText: "wake them?",//this is a button that goes to the next story
storyLink: 1

},
]
},
1: {
image: "img/gargoylesk.gif",
text: "im mad",
choices: [
{
choiceText: "Continue",
storyLink: 2
}
]
},
}

下面显示的是文本。它的工作方式是,它开始游戏,按顺序到0显示文本,然后将场景(故事链接)切换到下一个场景。这和"和你爸爸共进晚餐"很像。Codipen。

<span class="scene__text" data-bind="text: gameText"></span>
<button class="scene__choice" data-bind="text: choiceText, click: changeScene">Click Here to Start</button>

我不想在css中使用这种效果,因为我想控制打字器的速度。我有代码可以使用,如果我能以某种方式存储字符串。

让我知道如果我需要显示更多的代码,或进一步解释。一个工作代码的例子对我帮助最大。我想我只是完全错过了这些工作的语法。谢谢你的帮助!

我遵循了knockout文档,并阅读了关于json的w3。一直在获取"对象"结果就是他们的例子。不确定我是否可以检索显示的文本,然后将其发送到我编写的打字函数。

编辑:澄清一下,我想为每个独特的文本分配多个输入速度函数(也就是快,慢正常)。

您可以创建一个使用打字机效果注入文本的自定义绑定。

例如下面的typeWriter绑定:

  • 接受任意文本值,可观察或不可观察。
  • 创建一个新的可观察文本,它包含一个基于效果进度的子字符串。以""开头,以原始字符串结尾。
  • 将默认的text绑定到这个新值
  • 设置一个动态持续时间的动画(字符串中每个字符10ms)
    • 在每一帧中,经过的时间被用来计算正确的中间状态
    • Knockout将中间状态同步到DOM

如果您想使持续时间动态,您可以使用allBindings参数传递其他设置(参见文档中的第一个示例)

const texts = [
"Something short.",
"Medium length, Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud",
"A longer paragraph: Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
];
ko.bindingHandlers.typeWriter = {
init: (el, va) => {
const partialText = ko.observable("");
let animation;
const effect = ko.computed(() => {
const t0 = Date.now();
const fullText = ko.unwrap(va());
const duration = fullText.length * 10; // 10ms per char
animation = requestAnimationFrame(next);
function next() {
const p = (Date.now() - t0) / duration;
if (p >= 1) {
partialText(fullText);
}
partialText(
fullText.slice(0, Math.round(p * fullText.length))
);
animation = requestAnimationFrame(next);
}
});

ko.applyBindingsToNode(el, { text: partialText });
ko.utils.domNodeDisposal.addDisposeCallback(el, () => {
cancelAnimationFrame(animation);
effect.dispose();
});
}
}

const activeIdx = ko.observable(0);
const activeText = ko.pureComputed(() => texts[activeIdx()]);
const goNext = () => activeIdx((activeIdx() + 1) % texts.length);
ko.applyBindings({ activeText, goNext });
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<button data-bind="click: goNext">Next</button>
<h2>Typewriter text binding</h2>
<p data-bind="typeWriter: activeText"></p>

下面是一个使用模型对象的例子:(注意,只是为了好玩,我要求ChatGPT为我们写一个冒险:D)

// Set up view model
const activeStoryId = ko.observable(1)
// This forces a re-render if we ever want to loop back to the current story
.extend({ notify: "always" });

const activeStory = ko.pureComputed(() => 
story[activeStoryId()] ?? 
// Default to "The end" so user can restart
{ text: "The end", choices: [{ choiceText: "Back to start", storyLink: 1 }] }
);
const onChoice = ({ storyLink }) => activeStoryId(storyLink);
// Apply bindings
registerBinding();
ko.applyBindings({
onChoice,
activeStory
});
function registerBinding() {
ko.bindingHandlers.typeWriter = {
init: (el, va) => {
const partialText = ko.observable("");
let animation;
const effect = ko.computed(() => {
const t0 = Date.now();
const fullText = ko.unwrap(va());
const duration = fullText.length * 30; // 10ms per char
animation = requestAnimationFrame(next);
function next() {
const p = (Date.now() - t0) / duration;
if (p >= 1) {
partialText(fullText);
}
partialText(
fullText.slice(0, Math.round(p * fullText.length))
);
animation = requestAnimationFrame(next);
}
});
ko.applyBindingsToNode(el, {
text: partialText
});
ko.utils.domNodeDisposal.addDisposeCallback(el, () => {
cancelAnimationFrame(animation);
effect.dispose();
});
}
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<script>
const story = {"1":{"text":"You are standing in front of a big castle. What do you do?","choices":[{"choiceText":"Enter the castle","storyLink":"2"},{"choiceText":"Walk around the castle","storyLink":"3"}]},"2":{"text":"You are inside the castle. You see two doors. Which one do you choose?","choices":[{"choiceText":"Left door","storyLink":"4"},{"choiceText":"Right door","storyLink":"5"}]},"3":{"text":"You are walking around the castle. Suddenly, you are attacked by a monster. What do you do?","choices":[{"choiceText":"Fight the monster","storyLink":"6"},{"choiceText":"Run away","storyLink":"7"}]},"4":{"text":"You find a treasure chest. What do you do?","choices":[{"choiceText":"Open the chest","storyLink":"8"},{"choiceText":"Leave the chest and continue","storyLink":"9"}]},"5":{"text":"You find yourself in a room with no way out. What do you do?","choices":[{"choiceText":"Search for a hidden passage","storyLink":"10"},{"choiceText":"Scream for help","storyLink":"7"}]},"6":{"text":"You fought bravely, but the monster was too strong. You died.","choices":[]},"7":{"text":"You run away and find yourself in front of the castle. What do you do?","choices":[{"choiceText":"Enter the castle","storyLink":"2"},{"choiceText":"Walk around the castle","storyLink":"3"}]},"8":{"text":"You found a magical sword inside the chest. What do you do?","choices":[{"choiceText":"Leave the castle with the sword","storyLink":"11"},{"choiceText":"Continue exploring the castle","storyLink":"2"}]},"9":{"text":"You continue exploring the castle and find a secret passage. What do you do?","choices":[{"choiceText":"Enter the passage","storyLink":"12"},{"choiceText":"Leave the passage and continue","storyLink":"5"}]},"10":{"text":"You found a hidden passage and escaped from the room. What do you do?","choices":[{"choiceText":"Continue exploring the castle","storyLink":"2"},{"choiceText":"Leave the castle","storyLink":"11"}]}}
</script>
<div data-bind="with: activeStory">
<p data-bind="typeWriter: text" style="min-height: 50px"></p>

<!-- ko foreach: choices -->
<button data-bind="click: $root.onChoice, text: choiceText"></button>
<!-- /ko -->
</div>

最新更新