Как читать данные Json с помощью Knockout?

Я хочу создать эффект пишущей машинки с помощью нокаута, но я не могу хранить данные в своей таблице, чтобы создать указанный эффект. Я провел некоторое исследование в течение нескольких недель, и у меня нет фундаментальных знаний, чтобы наткнуться на эту проблему. Это мой первый раз, когда я спрашиваю о переполнении стека.


Это основано на этом codipen: 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, так как хочу контролировать скорость пишущей машинки. У меня есть код, который я мог бы использовать, если бы я мог как-то сохранить строку.

Дайте мне знать, если мне нужно показать больше кода или объяснить дальше. Пример рабочего кода помог бы мне больше всего. Я предполагаю, что мне просто полностью не хватает синтаксиса того, как они работают. Я ценю помощь!

Я следил за документацией по нокауту и ​​читал на w3 о json. Продолжал получать «Объект Объект» в результате со своими примерами. Не уверен, смогу ли я каким-то образом получить отображаемый текст, а затем отправить его в написанную мной функцию машинописи.

Редактировать: Чтобы уточнить, я хочу назначить несколько функций для скорости набора текста (также известной как быстрая, медленная нормальная) для каждого уникального текста.

Посмотрите на эту статью про трюки css . У него есть хороший учебник по имитации машинописи. В конце статьи есть хороший codepen где можно управлять скоростью машинки с помощью sass (второй параметр в @include typed после текста. Надеюсь поможет! По умолчанию 1.5, можете менять как хотите .

Abdelrahman 02.04.2023 21:25
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
1
62
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете создать пользовательскую привязку, которая вводит текст с помощью эффекта пишущей машинки.

Например, привязка typeWriter ниже:

  • Принимает любое текстовое значение, наблюдаемое или нет.
  • Создает новый наблюдаемый текст, содержащий подстроку на основе хода выполнения эффекта. Он начинается с "" и заканчивается исходной строкой.
  • Применяет привязку text по умолчанию к этому новому значению.
  • Устанавливает анимацию динамической продолжительности (10 мс на символ в строке)
    • В каждом кадре прошедшее время используется для расчета правильного промежуточного состояния.
    • 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>

Святое дерьмо, это именно то, что я искал! Спасибо за такой подробный ответ. Безумно полезно!

CodingLearningBH 03.04.2023 18:28

Другие вопросы по теме