挑战:胡编乱造故事生成器

在此挑战中,您将运用本模块至今为止所学的知识,创建一个有趣的随机胡编乱造故事生成器。在此过程中,我们将测试您对变量、数学、字符串和数组的掌握程度。玩得开心!

起始点

首先,点击下方代码面板中的播放按钮,在MDN Playground中打开提供的示例。然后,你将按照项目简介部分中的说明完成JavaScript功能。

html
<div>
  <label for="custom-name">Enter custom name:</label>
  <input id="custom-name" type="text" placeholder="" />
</div>
<fieldset>
  <legend>Choose locale:</legend>
  <label for="us">US</label
  ><input id="us" type="radio" name="uk-us" value="us" checked />
  <label for="uk">UK</label
  ><input id="uk" type="radio" name="uk-us" value="uk" />
</fieldset>
<div>
  <button class="generate">Generate random story</button>
</div>
<!-- Thanks a lot to Willy Aguirre for his help with the code for this assessment -->
<p class="story"></p>
js
// Complete variable definitions and random functions

const customName = document.getElementById("custom-name");
const generateBtn = document.querySelector(".generate");
const story = document.querySelector(".story");

function randomValueFromArray(array) {
  const random = Math.floor(Math.random() * array.length);
  return array[random];
}

// Raw text strings

// Willy the Goblin
// Big Daddy
// Father Christmas

// the soup kitchen
// Disneyland
// the White House

// spontaneously combusted
// melted into a puddle on the sidewalk
// turned into a slug and slithered away

// Partial return random string function

function returnRandomStoryString() {
  // It was 94 Fahrenheit outside, so :insertx: went for a walk. When they got to :inserty:, they stared in horror for a few moments, then :insertz:. Bob saw the whole thing, but was not surprised — :insertx: weighs 300 pounds, and it was a hot day.

  return storyText;
}

// Event listener and partial generate function definition

generateBtn.addEventListener("click", generateStory);

function generateStory() {
  if (customName.value !== "") {
    const name = customName.value;
  }

  if (document.getElementById("uk").checked) {
    const weight = Math.round(300);
    const temperature = Math.round(94);
  }

  // TODO: replace "" with the correct expression
  story.textContent = "";
  story.style.visibility = "visible";
}

项目简介

您已获得一些文本字符串和 JavaScript 函数;您需要编写必要的 JavaScript,将其变成一个能够执行以下操作的有效程序:

  • 在按下“生成随机故事”按钮时,生成一个随机的胡编乱造故事。
  • 如果用户在按下生成按钮前在“输入自定义名称”文本框中输入了自定义名称,则将故事中默认的名字“Bob”替换为自定义名称。
  • 如果在按下生成按钮前勾选了“英国”单选按钮,则将故事中默认的美国重量和温度单位转换为英国等效单位。
  • 每次按下按钮时,生成一个新的随机胡编乱造故事。

初始变量和函数

在 JavaScript 中,“完成变量定义和随机函数”注释下方,您有三个常量,它们存储了对以下元素的引用:

  • “输入自定义名称”文本框:customName
  • “生成随机故事”按钮:generateBtn
  • HTML 主体底部的 <p> 元素,故事将被复制到其中:story

此外,您还有一个名为 randomValueFromArray() 的函数,它接受一个数组作为输入,并随机返回数组中的一个元素。

在“原始文本字符串”注释下方,有一些注释掉的文本字符串,它们将作为我们程序的输入。我们希望您取消注释这些字符串,并将它们存储在常量中,如下所示:

  1. 将第一组三个字符串存储在一个名为 characters 的数组中。
  2. 将第二组三个字符串存储在一个名为 places 的数组中。
  3. 将第三组三个字符串存储在一个名为 events 的数组中。

完成 returnRandomStoryString() 函数

在“部分返回随机字符串函数”注释下方,您有一个部分完成的 returnRandomStoryString() 函数,其中包含一个长长的注释掉的文本字符串和一个返回名为 storyText 的值的 return 语句。

要完成此函数:

  1. 取消注释长文本字符串,并将其存储在一个名为 storyText 的变量中。这应该是一个模板字符串。
  2. 在模板字符串上方添加三个名为 randomCharacterrandomPlacerandomEvent 的常量。它们应该分别等于对 charactersplacesevents 数组调用 randomValueFromArray() 函数返回的随机字符串。
  3. 在模板字符串中,将 :insertx::inserty::insertz: 的实例替换为包含 randomCharacterrandomPlacerandomEvent 的嵌入式表达式。

完成 generateStory() 函数

在“事件监听器和部分生成函数定义”注释下方,您有几项代码:

  • 一行代码为 generateBtn 变量添加了一个 click 事件监听器,以便在单击它所代表的按钮时,会运行 generateStory() 函数。
  • 一个部分完成的 generateStory() 函数定义。在接下来的挑战中,您将在此函数内部填写代码以完成它并使其正常工作。

按照以下步骤完成函数:

  1. 创建一个名为 newStory 的新变量,并将其值设置为调用 returnRandomStoryString() 函数的结果。需要此函数才能在每次按下按钮时创建一个新的随机故事。如果我们直接将 newStory 设置为 storyText,我们只能生成一个新故事。
  2. 在第一个 if 块内,添加一个字符串替换方法调用,将 newStory 字符串中找到的名字 Bob 替换为 name 变量。在此块中,我们表示“如果 customName 文本输入框中有值,则将故事中的 Bob 替换为该自定义名称。”
  3. 在第二个 if 块中,我们检查 uk 单选按钮是否已被选中。如果是,我们希望将故事中的重量和温度值从磅和华氏度转换为英石和摄氏度。您需要执行以下操作:
    1. 查找将磅转换为英石以及将华氏度转换为摄氏度的公式。
    2. 在定义 weight 常量的行中,将 300 替换为一个将 300 磅转换为英石的计算。将 " stone" 连接到整个 Math.round() 调用的结果末尾。
    3. 在定义 temperature 变量的行中,将 94 替换为一个将 94 华氏度转换为摄氏度的计算。将 " Celsius" 连接到整个 Math.round() 调用的结果末尾。
    4. 在两个变量定义的正下方,添加另外两行字符串替换,将 300 pounds 替换为 weight 变量的内容,将 94 Fahrenheit 替换为 temperature 变量的内容。
  4. 最后,在函数的倒数第二行,将 story 变量(引用段落)的 textContent 属性设置为等于 newStory

提示和技巧

  • 您无需以任何方式编辑 HTML 和 CSS。
  • Math.round() 是一个内置的 JavaScript 方法,它将计算结果四舍五入到最接近的整数。
  • 有三个需要替换的字符串实例。您可以使用 replace() 方法,或者其他解决方案。

示例

你完成的应用程序应该像以下实时示例一样工作:

点击此处显示解决方案

完成的JavaScript应该如下所示:

js
// Complete variable definitions and random function

const customName = document.getElementById("custom-name");
const generateBtn = document.querySelector(".generate");
const story = document.querySelector(".story");

function randomValueFromArray(array) {
  const random = Math.floor(Math.random() * array.length);
  return array[random];
}

// Solution: Raw text strings

const characters = ["Willy the Goblin", "Big Daddy", "Father Christmas"];
const places = ["the soup kitchen", "Disneyland", "the White House"];
const events = [
  "spontaneously combusted",
  "melted into a puddle on the sidewalk",
  "turned into a slug and slithered away",
];

// Solution: Partial return random string function

function returnRandomStoryString() {
  const randomCharacter = randomValueFromArray(characters);
  const randomPlace = randomValueFromArray(places);
  const randomEvent = randomValueFromArray(events);

  let storyText = `It was 94 Fahrenheit outside, so ${randomCharacter} went for a walk. When they got to ${randomPlace}, they stared in horror for a few moments, then ${randomEvent}. Bob saw the whole thing, but was not surprised — ${randomCharacter} weighs 300 pounds, and it was a hot day.`;

  return storyText;
}

// Solution: Event listener and partial generate function definition

generateBtn.addEventListener("click", generateStory);

function generateStory() {
  let newStory = returnRandomStoryString();

  if (customName.value !== "") {
    const name = customName.value;
    newStory = newStory.replace("Bob", name);
  }

  if (document.getElementById("uk").checked) {
    const weight = `${Math.round(300 / 14)} stone`;
    const temperature = `${Math.round((94 - 32) * (5 / 9))} Celsius`;
    newStory = newStory.replace("300 pounds", weight);
    newStory = newStory.replace("94 Fahrenheit", temperature);
  }

  story.textContent = newStory;
  story.style.visibility = "visible";
}