首页  >  问答  >  正文

标题重写:值选择和变量赋值问题的故障排除

对于 Hangman 游戏,我有一些主题(例如:城市和动物)。

当用户选择其中一个主题时,结果应该是所选主题的随机项之一。例如:伦敦或斑马线等。

目前我只有所选主题的随机字母。

const cities = ["New York", "London", "Berlin"]
const animals = ["Alligator", "Alpaca", "Zebra"]

const topicsEl = document.querySelector("#topics")

function randomTopic(){
return topicsEl.value[Math.floor(Math.random()*topicsEl.value.length)]
}

topicsEl.addEventListener("change", function(){
    console.log(randomTopic());
})
<div class="select">
   <label for="topics">Choose a topic:</label>

   <select id="topics">
   <option value=cities>Cities</option>
   <option value=animals>Animals</option>
   </select>
</div>

P粉596161915P粉596161915186 天前386

全部回复(2)我来回复

  • P粉691461301

    P粉6914613012024-03-31 09:15:05

    在您现有的代码中,topicsEl.value 将是字符串“cities”或字符串“animals”(因为这些是 <select> 框中每个选项的值。)。这些不是您在 JavaScript 中定义的全局变量,它们只是 HTML 中包含的字符串。

    然后,在 randomTopic() 中,将该字符串作为数组访问,Javascript 将其解释为您希望将其视为该字符串中的字符数组。这就是为什么您会从单词中获得一个随机字母:"animals"[0] 是字母 a,"animals"[1] 是字母 n,依此类推。

    尝试要做的是从您命名为“城市”和“动物”的数组变量中选择一个随机项目,但您的函数不会尝试触及这些变量,它们只作用于 DOM 中包含的字符串。

    因此,您需要添加一个步骤,从 <select> 中的字符串值获取到您尝试访问的数组。

    您已将两个数组定义为全局变量;理论上,这些可以作为 window.citieswindow.animals 进行访问,因此您可以执行 window[topicsEl.value] 这将返回您尝试访问的数组....依赖于窗口并不是很好的做法不过,全局变量,所以我鼓励您将这对单独的变量切换到一个对象中以便于访问:

    const topics = {
      cities: ["New York", "London", "Berlin"],
      animals: ["Alligator", "Alpaca", "Zebra"]
    }
    
    const topicsEl = document.querySelector("#topics")
    
    function randomTopic() {
      // find the desired array:
      let topicArr = topics[topicsEl.value]
      // return a random element from that array:
      return topicArr[Math.floor(Math.random() * topicArr.length)]
    }
    
    topicsEl.addEventListener("change", function() {
      console.log(randomTopic());
    })

    回复
    0
  • P粉696605833

    P粉6966058332024-03-31 00:41:15

    您似乎在根据选择获取列表的随机值时遇到问题。

    目前,您正在选择 topicsEl.value 的随机字母,而不是关联主题列表的随机元素。

    您需要根据 topicsEl.value 确定要选择的列表。如果该值可以用作键(例如对于字典),则可以动态地实现这一点,但这也可以是静态完成。

    但是静态执行会导致重复代码,例如在每个新主题列表不断增长的 if-else-if 阶梯中:

    function randomTopic() {
      if (topicsEl.value === "cities") {
        // ... (use citites)
      } else if (topicsEl.value === "animals") {
        // ... (use animals)
      } // Etc. for every new topic
    }
    

    动态地执行此操作可以抽象出列表选择,从而保持功能简单。正如之前所建议的,可以使用字典来实现此目的。

    例如,字典的每个属性都可以是主题列表,然后您的选项值应与其相应属性的名称匹配:

    const topics = {
      cities: [/*...*/],
      animals: [/*...*/]
    };
    
    const topicsEl = document.querySelector("#topics");
    
    function randomTopic() {
      const list = topics[topicsEl.value];
      // ...
    }
    

    选择该列表中的随机项目类似于您当前选择随机字母的方式:

    function randomTopic() {
      const list = topics[topicsEl.value];
      return list[Math.floor(Math.random() * list.length)];
    }
    

    就我个人而言,如果索引生成位于单独的函数中,我发现这种随机选择更具可读性。示例:

    const edibles = ["cheese", "ham", "bread", "banana", "peanuts"];
    console.log(randomEdible());
    
    function randomEdible() {
      return edibles[randomInt(0, edibles.length - 1)];
    }
    
    function randomInt(max = 100, min = 0) {
      if (max < min) {
        [max, min] = [min, max]; // Swap
      }
      
      return Math.floor(Math.random() * (max - min + 1) + min); // +1 to include max
    }

    回复
    0
  • 取消回复