首页 > 解决方案 > 不同元素的 JavaScript 文本到语音

问题描述

我正在尝试使用文本到语音来帮助盲人用户使用我的网站作为我项目的一部分,它与我的输入、选择和按钮元素配合得很好。但我也想为标签元素等其他元素发声。我尝试使用 (for) 而不是 id 并尝试使用事件 (mouseover) 而不是 ( Click) 但它不起作用。你能帮我解决这个问题吗?或者有什么建议吗?这是我的代码:

<div class="all">

<form action="/action_page.php">
  <div class="container">
    <h1>Register</h1>
    Select Voice: <select id='voiceList'></select> <br><br>

    <p>Please fill in this form to create an account.</p>
    <hr>
    <input id='text1' type="text" placeholder="Enter Email" name="email" required>
    <label id="email" for="email"><b>Email</b></label>

<br/>
 <label for="email"><b>Name </b></label>
    <input id='text2' type="text" placeholder="Enter Name" name="email" required>
<br/>
    <label for="psw"><b>Password </b></label>
    <input id='text3' type="password" placeholder="Enter Password" name="psw" required>
<br/>
    <label for="psw-repeat"><b>Mobile </b></label>
    <input id='text4' type="password" placeholder="Mobile" name="psw-repeat" required>
    <br/>
        <label for="psw"><b>Gender </b></label>
   <select   id = "myList" style="font-size:15px;">
               <option >Male</option>
               <option >Female</option>

             </select>
             <hr>
    <button type="submit" class="registerbtn">Register</button>
  </div>

  <div class="container signin">
    <p>Already have an account? <a href="#">Sign in</a>.</p>
  </div>
</form>
</div>
<script>
        var txtInput1 = document.querySelector('#text1');
         var txtInput2 = document.querySelector('#email');

        var txtInput3 = document.querySelector('#text3');
        var txtInput4 = document.querySelector('#text4');

        var txtInput5 = document.querySelector('#myList');


        var voiceList = document.querySelector('#voiceList');
        var synth = window.speechSynthesis;
        var voices = [];

        //PopulateVoices();
        if(speechSynthesis !== undefined){
            speechSynthesis.onvoiceschanged = PopulateVoices; 
        }

        txtInput1.addEventListener('mouseover', ()=> {
            var toSpeak = new SpeechSynthesisUtterance(txtInput1.value);
            var selectedVoiceName = voiceList.selectedOptions[0].getAttribute('data-name');
            voices.forEach((voice)=>{
                if(voice.name === selectedVoiceName){
                    toSpeak.voice = voice;
                }
            });
            synth.speak(toSpeak);
        });

         txtInput2.addEventListener('mouseover', ()=> {
            var toSpeak = new SpeechSynthesisUtterance(txtInput2.value);
            var selectedVoiceName = voiceList.selectedOptions[0].getAttribute('data-name');
            voices.forEach((voice)=>{
                if(voice.name === selectedVoiceName){
                    toSpeak.voice = voice;
                }
            });
            synth.speak(toSpeak);
        });
txtInput3.addEventListener('click', ()=> {
            var toSpeak = new SpeechSynthesisUtterance(txtInput3.value);
            var selectedVoiceName = voiceList.selectedOptions[0].getAttribute('data-name');
            voices.forEach((voice)=>{
                if(voice.name === selectedVoiceName){
                    toSpeak.voice = voice;
                }
            });
            synth.speak(toSpeak);
        });
txtInput4.addEventListener('click', ()=> {
            var toSpeak = new SpeechSynthesisUtterance(txtInput4.value);
            var selectedVoiceName = voiceList.selectedOptions[0].getAttribute('data-name');
            voices.forEach((voice)=>{
                if(voice.name === selectedVoiceName){
                    toSpeak.voice = voice;
                }
            });
            synth.speak(toSpeak);
        });
        txtInput5.addEventListener('mouseover', ()=> {
            var toSpeak = new SpeechSynthesisUtterance(txtInput5.value);
            var selectedVoiceName = voiceList.selectedOptions[0].getAttribute('data-name');
            voices.forEach((voice)=>{
                if(voice.name === selectedVoiceName){
                    toSpeak.voice = voice;
                }
            });
            synth.speak(toSpeak);
        });

        function PopulateVoices(){
            voices = synth.getVoices();
            var selectedIndex = voiceList.selectedIndex < 0 ? 0 : voiceList.selectedIndex;
            voiceList.innerHTML = '';
            voices.forEach((voice)=>{
                var listItem = document.createElement('option');
                listItem.textContent = voice.name;
                listItem.setAttribute('data-lang', voice.lang);
                listItem.setAttribute('data-name', voice.name);
                voiceList.appendChild(listItem);
            });

            voiceList.selectedIndex = selectedIndex;
        }
    </script>

</body>

标签: javascripthtml

解决方案


Chrome 会在没有用户激活的情况下禁用 SpeechSynthesis。@Kaiido 本人的这个答案可能很有用。另请参阅有关弃用的 Google 群组的讨论。

简而言之,如果当前帧或其任何祖先曾经有过用户激活,我们将只允许 speak() 成功。

激活输入如下:

激活触发输入事件是其 isTrusted 属性为 true 且类型为以下之一的任何事件:

  • 改变
  • 点击
  • 上下文菜单
  • dblclick
  • mouseup
  • 指针向上
  • 重置
  • 提交
  • 触摸端

所以,我不认为mouseover事件会算作有效的触发器。

如果您的目的是让网站更易于访问,我会推荐上面提到的@Kaiido - 遵循 WAI 的建议。

如果您想使用SpeechSynthesis,也许您可​​以在标签旁边有一个小按钮,用户可能会点击并激活它来听到它?

我还可以通过一个初始屏幕来SpeechSynthesis开始这个项目,该屏幕需要用户单击以开始 - 并且该激活通过传播并允许SpeechSynthesis应用程序的其余部分使用。

请注意,这Web Speech API是一个实验性 API - 可能不适合生产。它的SpeechSynthesis一部分在浏览器中得到了合理的支持。但是,根据我使用此 API 的经验,我发现不同设备的行为有所不同,这可能是因为它有时会依赖设备的本机操作系统功能。


推荐阅读