Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
3.2k views
in Technique[技术] by (71.8m points)

javascript - Why is the voiceschanged event fired on page load?

In Chrome, the voiceschanged is firing on page load, so I don't need to call the function that has speechSynthesis.getVoices() initially in order for my empty array to be filled with voices as long as I have an event listener that calls it when voiceschanged is fired.

// 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();

I'm just trying to understand this behavior - MDN's explanation of when voiceschanged fires doesn't explain it as far as I can tell:

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.)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The event fires, because the list of voices changes when Chrome finishes making an API call to get the list of voices available only to Chrome users. Proof:

  • If I load my Speech Synthesis API-based web app, with Internet connection, I have 21 available voices, a few months ago, I only remember 10 or 15 or so.
  • If I do the same, without Internet connection, I only have two voices: Microsoft David Desktop and Microsoft Zira Desktop.

You probably notice that the two voices without Internet connection are rather boring and almost recognizable for being used in cheap audio production. But the Google Chrome ones are fluid and almost inflective. This event has to fire when the voices are loaded, of course. Take a quick glance at the W3C Errata in the Web Speech API Specification. Any time the voices are loaded, the voiceschanged event is fired....

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.

And, in fact, look at the last line of the MDN web docs you linked...

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 (from my open-source project PronounceThat)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...