admin管理员组

文章数量:1024016

I am trying to use text to speech to help the blind users to use my website as part of my project, it worked well with me for the input, select and button elements. But I want also to make voice for the other elements such label elements. I tried to use (for) instead of id and tried to use the event (mouseover) instead of ( Click) but it didn't work. Can you please help me with that or if there is any suggestions? this is my code:

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

I am trying to use text to speech to help the blind users to use my website as part of my project, it worked well with me for the input, select and button elements. But I want also to make voice for the other elements such label elements. I tried to use (for) instead of id and tried to use the event (mouseover) instead of ( Click) but it didn't work. Can you please help me with that or if there is any suggestions? this is my code:

<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>
Share Improve this question edited Jun 13, 2020 at 7:07 Saleh Refaai asked Jun 13, 2020 at 0:26 Saleh RefaaiSaleh Refaai 7093 gold badges14 silver badges26 bronze badges 2
  • 3 Good you want to help impaired people, but to better help them, only follow the WAI remendations. It's really nice of you to try to help them, but all impaired people won't have the same needs, and will already have assistive devices set up for their own needs. So the best we can do as web authors is to help these assistive devices do their job correctly. – Kaiido Commented Jun 16, 2020 at 1:48
  • 1 Agree with @Kaiido Also, I would suggest trying to utilize more on interaction with focus event instead of mouseover. – KTU Commented Jun 18, 2020 at 14:56
Add a ment  | 

2 Answers 2

Reset to default 5 +50

Chrome disables SpeechSynthesis without user activation. This answer by @Kaiido himself might be useful. Also refer to this discussion on the Google groups about the deprecation.

Briefly, we will only allow speak() to succeed if the current frame, or any of its ancestors, has ever had user activation.

Activation inputs are the following:

An activation triggering input event is any event whose isTrusted attribute is true and whose type is one of:

  • change
  • click
  • contextmenu
  • dblclick
  • mouseup
  • pointerup
  • reset
  • submit
  • touchend

So, I don't think mouseover event will count as a valid trigger.

If your purpose is to make the website more accessible, I'd remend what @Kaiido mentioned above - to follow the WAI remendations.

If you want to use SpeechSynthesis, maybe you can have a small button beside the label that the user might tab to and activate, to hear it?

I was also able to get SpeechSynthesis to work in this project here by having an initial screen that required the user to click to start - and that activation propagated through and allowed SpeechSynthesis usage for the rest of the app.

Do note that Web Speech API is an experimental API - and might not be suitable for production. The SpeechSynthesis part of it is reasonably supported across browsers. However, in my experience of using this API, I've found that the behaviour differs across devices, probably because it sometimes piggy backs on the device's native OS capabilities.

Just an option you might want to consider is using HTML5 text to speech

basic example:

let msg = new SpeechSynthesisUtterance('Hello World')
window.speechSynthesis.speak(msg)

In your case, do something like this for label elements:

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

I suggest to use jQuery so you can easy bind an event to selected elements and can use "this" reference, that way you don't have to have many variables:

example:

<label for="email"><b>Email </b></label>
<label for="name"><b>Name </b></label>
<label for="password"><b>Password </b></label>

Then:

$('label').mouseover(function() {
   var toSpeak = new SpeechSynthesisUtterance($(this).attr('for'));
   var selectedVoiceName = voiceList.selectedOptions[0].getAttribute('data-name');
   voices.forEach((voice)=>{
      if(voice.name === selectedVoiceName){
          toSpeak.voice = voice;
       }
     });
     synth.speak(toSpeak);
})

I am trying to use text to speech to help the blind users to use my website as part of my project, it worked well with me for the input, select and button elements. But I want also to make voice for the other elements such label elements. I tried to use (for) instead of id and tried to use the event (mouseover) instead of ( Click) but it didn't work. Can you please help me with that or if there is any suggestions? this is my code:

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

I am trying to use text to speech to help the blind users to use my website as part of my project, it worked well with me for the input, select and button elements. But I want also to make voice for the other elements such label elements. I tried to use (for) instead of id and tried to use the event (mouseover) instead of ( Click) but it didn't work. Can you please help me with that or if there is any suggestions? this is my code:

<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>
Share Improve this question edited Jun 13, 2020 at 7:07 Saleh Refaai asked Jun 13, 2020 at 0:26 Saleh RefaaiSaleh Refaai 7093 gold badges14 silver badges26 bronze badges 2
  • 3 Good you want to help impaired people, but to better help them, only follow the WAI remendations. It's really nice of you to try to help them, but all impaired people won't have the same needs, and will already have assistive devices set up for their own needs. So the best we can do as web authors is to help these assistive devices do their job correctly. – Kaiido Commented Jun 16, 2020 at 1:48
  • 1 Agree with @Kaiido Also, I would suggest trying to utilize more on interaction with focus event instead of mouseover. – KTU Commented Jun 18, 2020 at 14:56
Add a ment  | 

2 Answers 2

Reset to default 5 +50

Chrome disables SpeechSynthesis without user activation. This answer by @Kaiido himself might be useful. Also refer to this discussion on the Google groups about the deprecation.

Briefly, we will only allow speak() to succeed if the current frame, or any of its ancestors, has ever had user activation.

Activation inputs are the following:

An activation triggering input event is any event whose isTrusted attribute is true and whose type is one of:

  • change
  • click
  • contextmenu
  • dblclick
  • mouseup
  • pointerup
  • reset
  • submit
  • touchend

So, I don't think mouseover event will count as a valid trigger.

If your purpose is to make the website more accessible, I'd remend what @Kaiido mentioned above - to follow the WAI remendations.

If you want to use SpeechSynthesis, maybe you can have a small button beside the label that the user might tab to and activate, to hear it?

I was also able to get SpeechSynthesis to work in this project here by having an initial screen that required the user to click to start - and that activation propagated through and allowed SpeechSynthesis usage for the rest of the app.

Do note that Web Speech API is an experimental API - and might not be suitable for production. The SpeechSynthesis part of it is reasonably supported across browsers. However, in my experience of using this API, I've found that the behaviour differs across devices, probably because it sometimes piggy backs on the device's native OS capabilities.

Just an option you might want to consider is using HTML5 text to speech

basic example:

let msg = new SpeechSynthesisUtterance('Hello World')
window.speechSynthesis.speak(msg)

In your case, do something like this for label elements:

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

I suggest to use jQuery so you can easy bind an event to selected elements and can use "this" reference, that way you don't have to have many variables:

example:

<label for="email"><b>Email </b></label>
<label for="name"><b>Name </b></label>
<label for="password"><b>Password </b></label>

Then:

$('label').mouseover(function() {
   var toSpeak = new SpeechSynthesisUtterance($(this).attr('for'));
   var selectedVoiceName = voiceList.selectedOptions[0].getAttribute('data-name');
   voices.forEach((voice)=>{
      if(voice.name === selectedVoiceName){
          toSpeak.voice = voice;
       }
     });
     synth.speak(toSpeak);
})

本文标签: htmlJavaScript text to speech for different elementsStack Overflow