Search code examples
javascriptresponsivevoice

"onend" in ResponsiveVoice does not mean AFTER playing text?


I need to play some text and ONLY THEN perform the following actions (e.g. hiding the "pause" and "stop" buttons), but they are hidden IMMEDIATELY when I start playing the text. Simplified situation - see code.

Many thanks for the advice..

<!DOCTYPE html>
<html>
<body>

<script src='https://code.responsivevoice.org/responsivevoice.js'></script>

<script>

function Voice(id){
    var element = document.getElementById(id);
    var text = element.innerText;
    responsiveVoice.speak(text, "UK English Male", {onend: Hide("div1")});
}

function Hide(id){
    var element = document.getElementById(id);
    element.style="visibility: hidden";
}

</script>

<div id="div1">This is the first line.</div>

<div id="div2" onclick = 'Voice("div2")'>
This is the second line.
</div>
<br>
Click on the second line to play its text. The first line should be hidden after the message is played.<br>
But it is hidden IMMEDIATELY after clicking. What is wrong?
 
</body>
</html>

The solution is to use arrow: {onend: () => Hide()} instead of {onend: Hide()} (Thanks to CertainPerformance).

onstart:, onend: and rate: can even be used simultaneously. There is only one small problem - after changing the content of the page, there is a long delay when using the ResponsiveVoice function for the first time. See code:

<!DOCTYPE html>
<html>
<body> 

<script src='https://code.responsivevoice.org/responsivevoice.js'>
</script>

<script>

function Read(id){
    var element = document.getElementById(id);
    var text = element.innerText;
    responsiveVoice.speak(text, "UK English Male", {rate: 1.3, onstart: () => Show(), onend: () => Hide()});
}

function Show(){
    var element = document.getElementById("Pause");
    element.style="visibility: visible";
}

function Hide(){
    var element = document.getElementById("Pause");
    element.style="visibility: hidden";
}

</script>

<div id="div" onclick = 'Read("div")'>This is text to read.</div>
<br>
<input type = "button"
    id = "Pause"
    value = "Pause"
    style = "visibility: hidden" />
     
</body>
</html>
   


Solution

  • You need to pass a function that calls Hide, rather than calling Hide immediately:

    {onend: Hide("div1")}
    

    calls hide as soon as that line is evaluated. It needs to be:

    {onend: () => Hide("div1")}
    

    <!DOCTYPE html>
    <html>
    <body>
    
    <script src='https://code.responsivevoice.org/responsivevoice.js'></script>
    
    <script>
    
    function Voice(id){
        var element = document.getElementById(id);
        var text = element.innerText;
        responsiveVoice.speak(text, "UK English Male", {onend: () => Hide("div1")});
    }
    
    function Hide(id){
        var element = document.getElementById(id);
        element.style="visibility: hidden";
    }
    
    </script>
    
    <div id="div1">This is the first line.</div>
    
    <div id="div2" onclick = 'Voice("div2")'>
    This is the second line.
    </div>
    <br>
    Click on the second line to play its text. The first line should be hidden after the message is played.<br>
    But it is hidden IMMEDIATELY after clicking. What is wrong?
     
    </body>
    </html>