Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

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

dom events - Getting the list of voices in speechSynthesis (Web Speech API)

Following HTML shows empty array in console on first click:

<!DOCTYPE html>
<html>
    <head>
        <script>
            function test(){
                console.log(window.speechSynthesis.getVoices())
            }
        </script>
    </head>
    <body>
        <a href="#" onclick="test()">Test</a>
    </body>
</html>

In second click you will get the expected list.

If you add onload event to call this function (<body onload="test()">), then you can get correct result on first click. Note that the first call on onload still doesn't work properly. It returns empty on page load but works afterward.

Questions:

Since it might be a bug in beta version, I gave up on "Why" questions.

Now, the question is if you want to access window.speechSynthesis on page load:

  • What is the best hack for this issue?
  • How can you make sure it will load speechSynthesis, on page load?

Background and tests:

I was testing the new features in Web Speech API, then I got to this problem in my code:

<script type="text/javascript">
$(document).ready(function(){
    // Browser support messages. (You might need Chrome 33.0 Beta)
    if (!('speechSynthesis' in window)) {
      alert("You don't have speechSynthesis");
    }

    var voices = window.speechSynthesis.getVoices();
    console.log(voices) // []

    $("#test").on('click', function(){
        var voices = window.speechSynthesis.getVoices();
        console.log(voices); // [SpeechSynthesisVoice, ...]
    });
});
</script>
<a id="test" href="#">click here if 'ready()' didn't work</a>

My question was: why does window.speechSynthesis.getVoices() return empty array, after page is loaded and onready function is triggered? As you can see if you click on the link, same function returns an array of available voices of Chrome by onclick triger?

It seems Chrome loads window.speechSynthesis after the page load!

The problem is not in ready event. If I remove the line var voice=... from ready function, for first click it shows empty list in console. But the second click works fine.

It seems window.speechSynthesis needs more time to load after first call. You need to call it twice! But also, you need to wait and let it load before second call on window.speechSynthesis. For example, following code shows two empty arrays in console if you run it for first time:

// First speechSynthesis call
var voices = window.speechSynthesis.getVoices();
console.log(voices);

// Second speechSynthesis call
voices = window.speechSynthesis.getVoices();
console.log(voices);
Question&Answers:os

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

1 Answer

0 votes
by (71.8m points)

According to Web Speech API Errata (E11 2013-10-17), the voice list is loaded async to the page. An onvoiceschanged event is fired when they are loaded.

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.

So, the trick is to set your voice from the callback for that event listener:

// wait on voices to be loaded before fetching list
window.speechSynthesis.onvoiceschanged = function() {
    window.speechSynthesis.getVoices();
    ...
};

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...