stopPropagation gebruiken met text to speech

Status
Niet open voor verdere reacties.

backnext

Gebruiker
Lid geworden
29 apr 2016
Berichten
176
Hallo

Ik heb een kleine webpagina.
De bedoeling is dat ze klikken op een link en dan een stuk tekst horen (via responsivevoice).
Ik wil het onmogelijk maken om terwijl de tekst uitgesproken wordt nog eens te klikken. Daardoor worden zinnen door elkaar uitgesproken.
Ik dacht aan stopPropagation... maar zie niet hoe ik dat er in moet brengen.
Hier een klein voorbeeldje:
HTML:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>MenuView</title>

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

<script type="text/javascript">
	function klok()
	{ 
	responsiveVoice.cancel();
	var stuktekst1 = "dit is het begin";
	var stuktekst2 = "en dan het middelste stukje tekst";
	var stuktekst3 = "en hier is het laatste stukje tekst";
	var pause1 = 100;
	var pause2 = pause1+stuktekst1.length*60;
	var pause3 = pause2+stuktekst2.length*60;
	
	setTimeout(function(){ responsiveVoice.cancel(); responsiveVoice.speak(stuktekst1,'Dutch Female', {onstart: StartCallback, onend: EndCallback}); }, pause1);
	
	setTimeout(function(){ responsiveVoice.cancel(); responsiveVoice.speak(stuktekst2,'Dutch Female', {onstart: StartCallback, onend: EndCallback}); }, pause2);
	
	setTimeout(function(){ responsiveVoice.cancel(); responsiveVoice.speak(stuktekst3,'Dutch Female', {onstart: StartCallback, onend: EndCallback2}); }, pause3);
	}
</script>
</head>
<body oncontextmenu="return false;">



<table>
    <tr class="test">
        <td>
            <div style="text-align: center;" class="STOP" onmousedown="klok()">testje</div>
        </td>
    </tr>
</table>
<div id="INFO" style="border:1px solid #0d0;"></div>


<script>
function StartCallback() {
    console.log("Voice started");
		color = "red";
    document.body.style.background = color;
}
function EndCallback() {
    console.log("Voice ended");
		color = "black";
    document.body.style.background = color;
}
function EndCallback2() {
    console.log("Voice ended");
		color = "white";
    document.body.style.background = color;
}

</script>
</body>
</html>
 
Laatst bewerkt:
Ik heb ondertussen zelf een oplossing gevonden: zie hieronder.
... Tenzij er mensen zijn die iets beter weten...
Ik vond dat propagation stoppen niet zo'n goed idee is.

HTML:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>
<head>
<title>Untitled</title>
<style>
div#overlay {
	display: none;
	z-index: 2;
	background: #000;
	position: fixed;
	width: 100%;
	height: 100%;
	top: 0px;
	left: 0px;
	text-align: center;
}
div#stuk1 { 
	 	text-transform: uppercase;
    font-size: 1em;
    font-weight: bold;
		display: none;
	position: relative;
	z-index: 3;
	margin: 10px auto 0px auto;
	width: 80%; 
	height: 30px;
	background: #F5F;
	color: #000;
	text-align: center;
}
</style>
<script>
function toggleOverlay(){
	var overlay = document.getElementById('overlay');
	var specialBox = document.getElementById('stuk1');// stuk1 ipv specialBox
	overlay.style.opacity = .8;
	if(overlay.style.display == "block"){
		overlay.style.display = "none";
		specialBox.style.display = "none";
	} else {
		overlay.style.display = "block";
		specialBox.style.display = "block";
	}
}
</script>
</head>

<body>

<p>
<div id="stuk1">
<button onmousedown="toggleOverlay()">TERUG</button>
</div> 	
</p>

<!-- Start Overlay -->
<div id="overlay"></div>
<!-- End Overlay -->

<!-- Start Special Centered Box -->
<div id="specialBox">
  <p>Inhoud van overlay</p> 
  <button onmousedown="toggleOverlay()">TERUG</button>
</div>

</body>
</html>
 
Laatst bewerkt:
Kun je hier iets mee?
Code:
<!DOCTYPE html>
<html lang="nl">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>MenuView</title>
<link rel="stylesheet" href="style.css">
<script src="https://code.responsivevoice.org/responsivevoice.js"></script>
<script type="text/javascript">
function klok() {
   if(responsiveVoice.isPlaying()) return false;
   var voiceOfHolland = 'Dutch Female'; //-;
   var stuktekst1 = "dit is het begin";
   var stuktekst2 = "en dan het middelste stukje tekst";
   var stuktekst3 = "en hier is het laatste stukje tekst";
   var pause1 = 100;
   var pause2 = pause1 + stuktekst1.length * 60;
   var pause3 = pause2 + stuktekst2.length * 60;
   setTimeout(function(){
      responsiveVoice.speak(stuktekst1, voiceOfHolland);
   }, pause1);
   setTimeout(function(){
      responsiveVoice.speak(stuktekst2, voiceOfHolland);
   }, pause2);
   setTimeout(function(){
      responsiveVoice.speak(stuktekst3, voiceOfHolland);
   }, pause3);
}
</script>
</head>
Waarom al die setTimeout begrijp ik niet helemaal. Daar zal je een bedoeling mee hebben denk ik.

Suc6. Have fun.
 
Laatst bewerkt:
Een leuke spraak synthesizer. Ik heb er een functie voor gemaakt, hieronder deel ik de code.
Zet de volgende span om de tekst (de stippels) die je wilt laten uitspreken
<span class="speech" title="Klik en luister" onclick="Voice('speak', this.innerHTML)">.......<span>

In de <head>
Code:
<style type="text/css">
.speech {cursor: pointer; border-bottom: 1px dotted #999;}
.speech:before {content: "\1F50A";}
.btn {border: 1px solid #aaa; border-radius: 6px;}
</style>
<script src="https://code.responsivevoice.org/responsivevoice.js"></script>
<script type="text/javascript">
function Voice(Action, Text) {
  var TextStr = (typeof Text === 'undefined') ? '' : Text;
  if (Action === 'speak') {
    if(responsiveVoice.isPlaying()) return false;
    return responsiveVoice.speak(TextStr, 'Dutch Female', {pitch:1, rate:1, volume:1});
  }
  if (Action === 'cancel') return responsiveVoice.cancel();
  if (Action === 'pause')  return responsiveVoice.pause();
  if (Action === 'resume') return responsiveVoice.resume();
  return false;
}
</script>

In de <body>
Code:
<p><span class="speech" title="Klik en luister" onclick="Voice('speak', this.innerHTML)">Klik en luister naar deze tekst.</span></p>
<p>Hier staat <span class="speech" title="Klik en luister" onclick="Voice('speak', this.innerHTML)">een andere tekst.</span></p>
<input class="btn" type="button" value=" Stop"   onclick="Voice('cancel')">
<input class="btn" type="button" value=" Pause"  onclick="Voice('pause')">
<input class="btn" type="button" value=" Resume" onclick="Voice('resume')">
<p>De knoppen werken op elke tekst.</p>
Zet de luidspreker icon van de knoppen in de html als: &# 128266; (maar dan aan elkaar)

Edit: icon van iedere uit te spreken tekst in de css gezet.

Suc6. Have fun.
 
Laatst bewerkt:
bedankt bron, Ziet er zeker interessant uit maar aangezien ik geen specialist javascript ben moet ik er eventjes mijn tijd voor nemen om dit te begrijpen.
 
Beste bron. Ik heb wat verder nagedacht over je laatste scriptje. Zou het mogelijk zijn om zinnen die al aangeklikt zijn een bepaald kleur te geven? bv rood. En de rest in 't groen? Gepauzeerde tekst dan weer in 't oranje of zo? en het zou knap zijn als ze kunnen naar de volgende en vorige zin gaan door te klikken op een knop. Een tip?
 
Laatst bewerkt:
In je stylesheet:
Code:
.speech {cursor: pointer; border-bottom: 1px dotted #999;}
.speech:before {content: "\1F50A";}
.speech.beforeplay {background-color: #9f9;} /*groen*/
.speech.isplaying  {background-color: #ff9;} /*geel*/
.speech.afterplay  {background-color: #f99;} /*rood*/
.btn {padding: 3px 10px 5px 10px; border: 1px solid #aaa; border-radius: 6px; cursor: pointer;}
Gebruik in je html <span class="speech">Tekst die gesproken moet worden.</span>
Code:
<p><span class="speech" title="Beluister">Klik en luister naar deze tekst.</span></p>
<p>Hier staat <span class="speech" title="Beluister">een andere tekst.</span></p>
<input class="btn" type="button" value=" Stop"    onclick="SpeechButton('cancel')">
<input class="btn" type="button" value=" Pause"   onclick="SpeechButton('pause')">
<input class="btn" type="button" value=" Resume"  onclick="SpeechButton('resume')">
<input class="btn" type="button" value="Reset"  onclick="SpeechButton('reset')">
......
<!-- scripts staan direct boven /body -->
<script src="https://code.responsivevoice.org/responsivevoice.js"></script>
<script src="script.js"></script>
</body>
</html>
Bestand script.js met dit:
Code:
var i;
// ResponsiveVoice instellingen
var parameters = { pitch: 1, rate: 1, volume: 1, onend: voiceEndCallback }
// get class='speech'
var SpeechList = document.getElementsByClassName("speech");
// afhandeling buttons
function SpeechButton(Action) {
  if (Action === 'cancel') return responsiveVoice.cancel();
  if (Action === 'pause')  return responsiveVoice.pause();
  if (Action === 'resume') return responsiveVoice.resume();
  if (Action === 'reset') {
    for (i = 0; i < SpeechList.length; i++) {
      SpeechList[i].setAttribute("class", "speech beforeplay");
    }
    return responsiveVoice.cancel();
  }
  return false;
}
// na het spreken van een tekst
function voiceEndCallback() {
  for (i = 0; i < SpeechList.length; i++) {
    if (SpeechList[i].getAttribute("class").indexOf("isplaying") > -1) {
      SpeechList[i].setAttribute("class", "speech afterplay");
    }
  }
}
// na een click op class='speech'
var fnSpeech = function() {
  if (responsiveVoice.isPlaying() == false) {
    responsiveVoice.speak(this.innerHTML, 'Dutch Female', parameters);
    this.setAttribute("class", "speech isplaying");
  }
};
// beginwaarde
for (i = 0; i < SpeechList.length; i++) {
  SpeechList[i].setAttribute("class", "speech beforeplay");
  SpeechList[i].addEventListener("click", fnSpeech, false);
}
Je laatste vraag over vorige en volgende tekst heb ik er niet in verwerkt. Een aparte kleur bij Pause en Resume wordt door ResponsiveVoice alleen in Chrome ondersteunt dus dat heb ik weggelaten. Je kunt in de css de kleur instellen voor: nog niet gesproken, wordt nu gesproken, en is al gesproken.

Suc6. Have fun.
 
Laatst bewerkt:
Werkt heel goed. Hier kan ik zeker mee verder. Heel erg bedankt.
Ik zoek nu nog een manier om de knoppen bovenaan de tekst vast te zetten zodat ze bereikbaar blijven als je door de tekst scrolt.
 
Tja, Zelf al iets gevonden voor de knoppen, is niet zo moeilijk. nog eens bedankt.
 
Zou het mogelijk zijn om dit systeem te gebruiken met tekstjes die apart staan. Bv. in een .txt bestandje in een mapje van dezelfde webruimte?
Ik ben van plan om enkele tekstjes wekelijks te veranderen. Dan moet ik niet iedere keer zo'n html pagina opmaken...
 
Ik heb ondertussen wat verder gezocht om met externe teksten te werken en kan nu stukken van externe tekst (.txt) ophalen met ajax.
Hoe kan ik dit in een lus steken zodat iedere zin apart opgehaald wordt tot aan het einde van de tekst.
Hieronder wat ik al heb (met voor 't gemak bovenstaande scriptje in de code inbegrepen.
voorlopig werk ik met genummerde zinnen...

HTML:
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <title>test</title>
    <link rel="stylesheet" href="http://www.w3schools.com/lib/w3.css">
    <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
    <style type="text/css">
        .speech {
            cursor: pointer;
            border-bottom: 1px dotted #999;
        }

            .speech:before {
                content: "\25B6";
            }

            .speech.beforeplay {
                background-color: #9f9;
            }
            /*groen*/
            .speech.isplaying {
                background-color: #ff9;
            }
            /*geel*/
            .speech.afterplay {
                background-color: #f99;
            }
        /*rood*/
        .btn {
            padding: 3px 10px 5px 10px;
            border: 1px solid #aaa;
            border-radius: 6px;
            cursor: pointer;
        }
    </style>
<script type="text/javascript">

        var http;
        var stuktext;
        var positie;
        var positie2;
     
// ajax
    if (window.ActiveXObject) {
    http = new AcitveXObject("Microsoft.XMLHTTP");
    }
    else if (window.XMLHttpRequest) {
    http = new XMLHttpRequest();
    }
        //volledige txt file ophalen
       
    http.open ('get','twintig.txt');
    http.onreadystatechange = handleText;
    http.send(null);

    function handleText() {
    if (http.readyState == 4) {
        var text = http.responseText;  //volledige txt in variabele

 // in lus verwerken? ******************* 
    // posities begin en einde van stuktext
    var positie = text.search("17");
    var positie2 = text.search("18");
    //stuktext ophalen
    var stuktext = text.slice(positie, positie2);
    document.getElementById("stuktext").innerHTML = stuktext;
// in lus verwerken? ******************* 
     }
    }
</script>

</head>
<body onload="handleText()">
 
    <div class="w3-container">

        <p><span class="speech" title="LUISTER" id="stuktext"></span></p>

    </div>

    <!--onderstaande script moet weg en extern gebracht worden-->

    <script>
    
        var i;
        // ResponsiveVoice instellingen
        var parameters = { pitch: 1, rate: 1, volume: 1, onend: voiceEndCallback };
        // get class='speech'
        var SpeechList = document.getElementsByClassName("speech");
        // afhandeling buttons
        function SpeechButton(Action) {
            if (Action === 'cancel') return responsiveVoice.cancel();
            if (Action === 'pause') return responsiveVoice.pause();
            if (Action === 'resume') return responsiveVoice.resume();
            if (Action === 'reset') {
                for (i = 0; i < SpeechList.length; i++) {
                    SpeechList[i].setAttribute("class", "speech beforeplay");
                }
                return responsiveVoice.cancel();
             }
            return false;
        }
        // na het spreken van een tekst
        function voiceEndCallback() {
            for (i = 0; i < SpeechList.length; i++) {
                if (SpeechList[i].getAttribute("class").indexOf("isplaying") > -1) {
                    SpeechList[i].setAttribute("class", "speech afterplay");
                }
            }
        }
        // na een click op class='speech'
        var fnSpeech = function () {
            if (responsiveVoice.isPlaying() === false) {
                responsiveVoice.speak(this.innerHTML, 'Dutch Female', parameters);
                this.setAttribute("class", "speech isplaying");
            }
        };
        // beginwaarde
        for (i = 0; i < SpeechList.length; i++) {
            SpeechList[i].setAttribute("class", "speech beforeplay");
            SpeechList[i].addEventListener("click", fnSpeech, false);
        }
    </script>

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
    <script src="https://code.responsivevoice.org/responsivevoice.js"></script>
</body>
 
De tekstjes die door de vorige code:
Code:
<p><span class="speech" title="LUISTER" id="stuktext"></span></p>
op het scherm gezet worden, wil ik in een 'w3-tag' brengen op de volgende manier:
Code:
 <h2 class="w3-tag w3-padding-8 w3-orange drop-shadow lifted"><span class="speech" id="zin1"></span></h2>

Hierbij wordt de css background stijl op de zin zelf gezet. Die verkleurt dus eerst naar het ene kleur, dan naar het ander.
Ik wil echter dat de volledige w3-tag als knop functioneert en ook volledig van kleur veranderd.
Ik veronderstel dat de 2 'classes' samen moeten gebracht worden, maar het lukt me op geen enkele manier. Enig idee?
 
Om je te helpen met een handiger opzet. Zie bijlage.
Style en script elk in een apart bestand.

Je andere vraag heb ik niet getest maar je kunt het proberen
Code:
<h2 class="w3-tag w3-orange drop-shadow lifted"><span class="w3-padding-8 speech"></span></h2>

h2 .speech {
  display: block;
}
 

Bijlagen

  • speech.zip
    1,7 KB · Weergaven: 35
Laatst bewerkt:
bedankt bron. Die 'display: block;', dat had ik moeten weten maar niet aan gedacht. En die 'padding' veranderen van plaats is de nagel op de kop. Weer helemaal wat ik (al een paar dagen) zocht. Ik bekijk de bijlage zo vlug als mogelijk.
 
bron, ivm de files in de bijlage: Als ik het goed heb, heb je het "ajax-deeltje" in de externe script gestopt als volgt:

Code:
// ajax tekst filename
var FileName = "twintig.txt";
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
	if (this.readyState == 4 && this.status == 200) {
		var FileText = this.responseText;
		//startpositie (vanaf 0) en aantal tekens
		var TextSlice = FileText.substr(0, 23);
		document.getElementById("text1").innerHTML = TextSlice;
		var TextSlice = FileText.substr(24, 12);
		document.getElementById("text2").innerHTML = TextSlice;
	}
};
xhttp.open("GET", FileName, true);
xhttp.send();

Ik had het ajax-deel tot nu toe in iedere "text.html-file" intern gezet. Zie hieronder. Het voordeel hier is dat ik een lus heb om de zinnen er 1 voor 1 uit te halen.
Het nadeel is dat ik intern blijf en dus iedere keer moet kopiëren naar een nieuwe tekstfile. Misschien moet ik het ajax-deel toch extern brengen en innerhtml gebruiken om de variabele tekstlocatie naar het externe script te brengen?

Code:
 <script type="text/javascript">
        var http;
        var stuktext;
        var pretext;
        var text;
        // ajax
        if (window.ActiveXObject) {
            http = new AcitveXObject("Microsoft.XMLHTTP");
        }
        else if (window.XMLHttpRequest) {
            http = new XMLHttpRequest();
        }
        //volledige txt file ophalen
        http.open('get', '../../sp_tekst/ezel.txt');
        http.onreadystatechange = handleText;
        http.send(null);

        function handleText() {
            if (http.readyState == 4) {
                var pretext = http.responseText;  //volledige txt in variabele
                var text = pretext.split(".");
                var stuktext = "";
                var i;
                for (i = 1; i < text.length; i++) {
                    var stuktext = text.slice(i - 1, i);
                    document.getElementById("zin" + i).innerHTML = stuktext;
                }
            }
        }
    </script>
 
Ondertussen dit op een eenvoudige manier opgelost door in de tekstfile het volgende te zetten:

Code:
 <script type="text/javascript">var link;var link = '../../sp_tekst/tekst1.txt';</script>

en in het externe script het volgende toe te voegen:

Code:
var http;
var stuktext;
var pretext;
var text;
if (window.ActiveXObject) {
    http = new AcitveXObject("Microsoft.XMLHTTP");
}
else if (window.XMLHttpRequest) {
    http = new XMLHttpRequest();
}
//volledige txt file ophalen
http.open('get', link);
http.onreadystatechange = handleText;
http.send(null);
function handleText() {
    if (http.readyState == 4) {
        var pretext = http.responseText;
        var text = pretext.split(".");
        var stuktext = "";
        var i;
        for (i = 1; i < text.length; i++) {
            var stuktext = text.slice(i - 1, i);
            document.getElementById("zin" + i).innerHTML = stuktext;
        }
    }
}
 
Aanpassing in de zip van post #13
html:
Code:
<div class="w3-container">
  <p><span class="speech" title="LUISTER" id="zin1"></span></p>
  <p><span class="speech" title="LUISTER" id="zin2"></span></p>
</div>
javascript:
Code:
// na een click op class='speech'
var fnSpeech = function () {
  ....
}

// beginwaarde
for (var i = 0; i < SpeechList.length; i++) {
  ....
}

// stuur elke zin naar een tag met een unieke id (zin1, zin2, zin3, enz.)
function fnHandleText(FileText) {
  var TextArray = FileText.split(".");
  for (var i = 0; i < TextArray.length; i++) {
    document.getElementById("zin"+(i+1)).innerHTML = TextArray[i];
  }
}

// ajax get tekst file
// volgende regel in de html in een script tag
// var TextFileName = "../../sp_tekst/ezel.txt";
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
  if (this.readyState == 4 && this.status == 200) {
    fnHandleText(this.responseText);
  }
};
xhttp.open("GET", TextFileName, true);
xhttp.send();
Het tekstbestand (var TextFileName) waarin de zinnen staan wordt opgesplitst bij iedere punt zodat je losse zinnen krijgt.
Elke zin wordt in de html bij een id gezet. De id's heten: zin1, zin2, zin3, enzovoort.

**edit
Je kunt inderdaad de naam van het 'bestand met de zinnen' in de html zetten:
Code:
<script type="text/javascript">
var TextFileName = "../../sp_tekst/ezel.txt";
</script>
 
Laatst bewerkt:
bron. Dat is nog eens een stuk compacter en overzichtelijker zo. Werkt goed. Bedankt.
Nog een klein vraagje: Ik heb in de css volgende:
Code:
 html, body, * {
            -webkit-touch-callout: none; /*no touch & hold feature*/
            -webkit-user-select: none; /* no select text feature*/
            -moz-user-select: none; /* no select text feature*/
            -ms-user-select: none; /* no select text feature*/
            user-select: none; /* no select text feature*/
            -webkit-appearance: none; /* no platform-native styling*/
        }

body {
            font: 14px/1.5 Arial, sans-serif;
            text-align: center;
            color: #333;
            background: #96ceb4;
        }
Op welke manier kan ik die twee samenbrengen of is dat niet mogelijk?
 
Die kun je beter niet verder samenvoegen, een aantal hiervan zijn al samengevoegd.
De 6 regels onder html, body, * zijn eigenlijk 18 regels die al zijn samengevoegd.
Als je de 4 regels (onder body) bij de 6 regels zou zetten dan zijn de 4 regels ook van toepassing op html en * en dat is niet de bedoeling.

In dit geval zou samenvoegen eventueel kunnen maar je krijgt dan problemen als je de html en/of css verder uitbreidt. De css zo laten is het meest handig.
De 6 regels bij html, body, * gaan over functionaliteti.
De 4 regels bij body gaan over vormgeving.
 
Status
Niet open voor verdere reacties.
Steun Ons

Nieuwste berichten

Terug
Bovenaan Onderaan