为什么在页面加载时触发 voicechanged 事件?

Why is the voiceschanged event fired on page load?

在 Chrome 中,voiceschanged 在页面加载时触发,所以我不需要最初调用具有 speechSynthesis.getVoices() 的函数来让我的空数组成为只要我有一个在 voiceschanged 被触发时调用它的事件侦听器,就会充满声音。

// Store voices
let voices = [];

function getVoices() {
  voices = speechSynthesis.getVoices();

  // Create an option for each voice in array
  voices.forEach((voice) => {
    const option = document.createElement('option');

    option.value = voice.name;
    option.innerText = `${voice.name} ${voice.lang}`;

    voicesSelect.appendChild(option);
  });
}

// Voices changed
speechSynthesis.addEventListener('voiceschanged', getVoices);

// Not needed (in Chrome at least) because voiceschanged event fires on page load, calling getVoices due to event listener (trying to figure out why)
// getVoices();

我只是想了解这种行为 - 据我所知,MDN 的 explanation 关于何时触发变声并没有解释:

The voiceschanged event of the Web Speech API is fired when the list of SpeechSynthesisVoice objects that would be returned by the SpeechSynthesis.getVoices() method has changed (when the voiceschanged event fires.)

事件触发,因为当 Chrome 完成调用 API 以获取仅供 Chrome 用户使用的语音列表时,语音列表发生变化。证明:

  • 如果我加载我的基于语音合成 API 的网络应用程序,通过互联网连接,我有 21 种可用的声音,几个月前,我只记得 10 或 15 种左右。
  • 如果我这样做,没有互联网连接,我只有两种声音:Microsoft David Desktop 和 Microsoft Zira Desktop。

您可能注意到,没有互联网连接的两个声音相当无聊,几乎可以识别用于廉价音频制作。但是 Google Chrome 是流动的并且几乎是屈折的。当然,这个事件必须在声音加载时触发。快速浏览 W3C Errata in the Web Speech API Specification。任何时候加载语音,都会触发 voiceschanged 事件....

voiceschanged: Fired when the contents of the SpeechSynthesisVoiceList, that the getVoices method will return, have changed. Examples include: server-side synthesis where the list is determined asynchronously, or when client-side voices are installed/uninstalled.

事实上,看看您链接的 MDN web docs 的最后一行...

With Chrome however, you have to wait for the event to fire before populating the list, hence the bottom if statement seen below.

Speech Synthesis API-Based Source Code(来自我的开源项目 PronounceThat)