为啥我的 javascript 一直引用相同的 innerHTML?

Posted

技术标签:

【中文标题】为啥我的 javascript 一直引用相同的 innerHTML?【英文标题】:Why does my javascript keep referring to the same innerHTML?为什么我的 javascript 一直引用相同的 innerHTML? 【发布时间】:2021-09-05 07:56:44 【问题描述】:

我正在使用 javascripthtml 构建语音助手,在添加天气命令(最后一个“else if”)之前,代码运行良好,但现在,每次我尝试向程序询问其他内容时,例如日期,时间,innerHTML 不断显示天气。我尝试了很多不同的东西,但仍然无济于事。为什么 innerHTML 一直显示天气而不是我的其他命令?

这是我的代码,因为它需要使用麦克风,所以这里是网站:https://voice-assistant-development.stcollier.repl.co/。你可以自己试试看我的意思。

function record() 
 var recognition = new webkitSpeechRecognition();
 recognition.lang = "en-GB";
 recognition.start();
 recognition.onresult = function(event) 
   let transcript = event.results[0][0].transcript;
var str = transcript;
//Weather Code
var input = "Detroit";
var desc = document.querySelector('#output');


fetch('https://api.openweathermap.org/data/2.5/weather?q='+input+'&units=imperial&appid=6a3b95f23e761e707120f86b0eed7d55')
.then(response => response.json())
.then(data => 
  var tempValue = data['main']['temp'];
  var nameValue = data['name'];
  var descValue = data['weather'][0]['description'];
  var humidvalue=data['main']['humidity'];
  var mintemp=data['main']['temp_min'];
  var maxtemp=data['main']['temp_max'];
  var weather_now = "It's " + tempValue +" degrees Farenheight outsite currently, with a low of " +mintemp + " degrees Farenheight and a high of " + maxtemp + " degrees Farenheight. The humidity percentage for today is " + humidvalue + "%. The current weather is "  + descValue + ".";

  
desc.innerHTML = weather_now;

)
//End of Weather Code
//Date Code
const d = new Date();
var weekday = new Array(7);
  weekday[0] = "Sunday";
  weekday[1] = "Monday";
  weekday[2] = "Tuesday";
  weekday[3] = "Wednesday";
  weekday[4] = "Thursday";
  weekday[5] = "Friday";
  weekday[6] = "Saturday";
var wkday = weekday[d.getDay()];
const months = ["January","February","March","April","May","June","July","August","September","October","November","December"];
var msg_date = "It's " + wkday + ", " + months[d.getMonth()] + " " + d.getDate() + "th " + d.getFullYear() + "."
//End of Date
//Time Code
function formatAMPM(date) 
  var hours = date.getHours();
  var minutes = date.getMinutes();
  var ampm = hours >= 12 ? 'PM' : 'AM';
  hours = hours % 12;
  hours = hours ? hours : 12; // the hour '0' should be '12'
  minutes = minutes < 10 ? '0'+minutes : minutes;
  var strTime = "It's " + hours + ':' + minutes + ' ' + ampm;
  return strTime;

var msg_time = formatAMPM(new Date);
//End of Time
var msg_hello = ['Hello!', 'Hello, User!', 'Hi!', 'Hello! How are you doing?'];
var msg_notunderstood = ["I'm not sure what you mean.", "I don't understand. Maybe try rephrasing?", "I'm sorry, I don't understand. Please try again."]
var affirmative_msg = ['Here you go!', 'Sure thing!']
if (str.includes('hello')) 
 responsiveVoice.speak(msg_hello[Math.floor(Math.random()*msg_hello.length)], 'US English Female');
 else if (str.includes('date')) 
  document.getElementById('output').innerHTML = msg_date
  responsiveVoice.speak(msg_date, 'US English Female')
 else if (str.includes('time')) 
  document.getElementById('output').innerHTML = msg_time
  responsiveVoice.speak(msg_time, 'US English Female')
 else if (str.includes('email')) 
  window.open("mailto:")
 else if (str.includes('weather')) 
  document.getElementById('output').innerHTML = weather_now
  responsiveVoice.speak(weather_now, 'US English Female')
 else 
  document.getElementById('output').innerHTML = "I don't know what you mean."
  responsiveVoice.speak(msg_notunderstood[Math.floor(Math.random()*msg_notunderstood.length)], 'US English Female');

    document.getElementById('speechToText').value = event.results[0][0].transcript;
  


//Mic Trigger Key
document.body.onkeyup = function(e)
    if(e.keyCode == 32)
      record()
    
<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <meta http-equiv="X-UA-Compatible" content="ie=edge">
   <title>Document</title>
</head>
<body>
   <label for="Speech Recognition">Speech Recognition</label>
   <input type="text" name="" id="speechToText" placeholder="Speak Something" disabled="disabled" value="">
   <button onclick="record()">Record</button>
   <p id="output"></p>
      <h1 class="name" id="name"></h1>
      <p class="desc"></p>
   <script src="https://code.responsivevoice.org/responsivevoice.js?key=x9uXdCB8"></script>
   <script src="script.js"></script>
</body>
</html>

感谢您的帮助。我真的很感激。

【问题讨论】:

【参考方案1】:

问题是天气检索获取在您的记录循环内 - 没有条件 - 所以它每次都会执行。因为获得结果需要一点时间,所以它会覆盖您的任何其他结果。我建议将它放在另一个函数中并存储变量,以便在需要时获取它。如果你把它放在window.onload 事件中,它会在页面加载时触发,所以当语音命令请求它时不会有延迟。

let weather_now

window.onload = function() 
  fetch('https://api.openweathermap.org/data/2.5/weather?q=' + input + '&units=imperial&appid=6a3b95f23e761e707120f86b0eed7d55')
    .then(response => response.json())
    .then(data => 
      let tempValue = data['main']['temp'];
      let nameValue = data['name'];
      let descValue = data['weather'][0]['description'];
      let humidvalue = data['main']['humidity'];
      let mintemp = data['main']['temp_min'];
      let maxtemp = data['main']['temp_max'];
      weather_now = "It's " + tempValue + " degrees Farenheight outsite currently, with a low of " + mintemp + " degrees Farenheight and a high of " + maxtemp + " degrees Farenheight. The humidity percentage for today is " + humidvalue + "%. The current weather is " + descValue + ".";
    )


function record() 
  var recognition = new webkitSpeechRecognition();
  recognition.lang = "en-GB";
  recognition.start();
  recognition.onresult = function(event) 
    let transcript = event.results[0][0].transcript;
    var str = transcript;
    //Weather Code
    let input = "Detroit";
    let desc = document.querySelector('#output');
    //Date Code
    const d = new Date();
    let weekday = new Array(7);
    weekday[0] = "Sunday";
    weekday[1] = "Monday";
    weekday[2] = "Tuesday";
    weekday[3] = "Wednesday";
    weekday[4] = "Thursday";
    weekday[5] = "Friday";
    weekday[6] = "Saturday";
    let wkday = weekday[d.getDay()];
    const months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
    var msg_date = "It's " + wkday + ", " + months[d.getMonth()] + " " + d.getDate() + "th " + d.getFullYear() + "."
    //End of Date    
    let msg_time = formatAMPM(new Date);
    //End of Time
    let msg_hello = ['Hello!', 'Hello, User!', 'Hi!', 'Hello! How are you doing?'];
    let msg_notunderstood = ["I'm not sure what you mean.", "I don't understand. Maybe try rephrasing?", "I'm sorry, I don't understand. Please try again."]
    let affirmative_msg = ['Here you go!', 'Sure thing!']
    if (str.includes('hello')) 
      responsiveVoice.speak(msg_hello[Math.floor(Math.random() * msg_hello.length)], 'US English Female');
     else if (str.includes('date')) 
      document.getElementById('output').innerHTML = msg_date
      responsiveVoice.speak(msg_date, 'US English Female')
     else if (str.includes('time')) 
      document.getElementById('output').innerHTML = msg_time
      responsiveVoice.speak(msg_time, 'US English Female')
     else if (str.includes('email')) 
      window.open("mailto:")
     else if (str.includes('weather')) 
      document.getElementById('output').innerHTML = weather_now
      responsiveVoice.speak(weather_now, 'US English Female')
     else 
      document.getElementById('output').innerHTML = "I don't know what you mean."
      responsiveVoice.speak(msg_notunderstood[Math.floor(Math.random() * msg_notunderstood.length)], 'US English Female');
    
    document.getElementById('speechToText').value = event.results[0][0].transcript;
  


// Time 
function formatAMPM(date) 
  let hours = date.getHours();
  let minutes = date.getMinutes();
  let ampm = hours >= 12 ? 'PM' : 'AM';
  hours = hours % 12;
  hours = hours ? hours : 12; // the hour '0' should be '12'
  minutes = minutes < 10 ? '0' + minutes : minutes;
  let strTime = "It's " + hours + ':' + minutes + ' ' + ampm;
  return strTime;


//Mic Trigger Key
document.body.onkeyup = function(e) 
  if (e.keyCode == 32) 
    record()
  

【讨论】:

【参考方案2】:

目前我无法在我的计算机上尝试复制,但我怀疑问题与异步代码执行有关。当您说fetch(...).then(...) 时,您是在说“去向 OpenWeatherMap 索取数据,一旦你得到它,然后...这样做。”但是当那个 fetch 函数在做它的事情时,你的文件的其余部分并不仅仅是停下来等待。它继续执行以下行。我猜会发生什么,它会通过您以后的所有代码,解析语音并适当地响应,然后fetch 完成并使用天气信息更新 div。也许您想在与助手响应不同的 html 元素中显示此天气数据?

【讨论】:

以上是关于为啥我的 javascript 一直引用相同的 innerHTML?的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript为啥用push方法为数组添加新的索引的时候,会出现这种情况?

为啥我的机器人的 message.js 一直向我发送相同的错误,我该如何解决?

为啥 JavaScript 会根据结构相同的字符串猜测两个不同的时区?

为啥我的音频功能一直循环而不是一直运行?

为啥解引用运算符 (*) 也用于声明指针?

为啥我的代码没有执行正确的答案/回文检查器 javascript