I'm tring to code a tic tac toe game by using buttons, and in my plan I want to store a button.innertext to be a variable so that I can use it to make the judgement of game result more convinient. Here's the code, for simplicity, I only put one button here
const b1 = document.getElementById("b1");
const b = [b1];
let b1T = b1.innerText;
let xo = true;
show();
function show() {
for(let i = 0; i < 9; i++) {
b[i].addEventListener("click",go)
}
}
//decide x or o is displayed
function go(event) {
if(xo) {
event.target.innerText = "X";
event.target.disabled = true;
xo = false;
} else {
event.target.innerText = "O";
event.target.disabled = true;
xo = true;
}
}
function decide() {
if(b1T === "X"){
//do something
}
}
When I tried to write the part in function decide, I noticed that b1T didn't change it's value to "X" or "O", by console.log(b1T) I only got empty like I setted in HTML file <button id = "b1"><button>, but when I typed console.log(b1.innerText) it did show the innerText of it. Am I settig the biT variable in the wrong place or something else?
Get the text from your button inside the decide function instead. Your button is changing it's inner text when you press it, so you need to get the latest text (not the oldest one).
function decide() {
const b1 = document.getElementById("b1");
if(b1.innerText === "X"){
//do something
}
}
This is happening because the code on line number 2, i.e.
let b1T = b1.innerText
is run only during page load. You need to set that again to either "X" or "O" when handling the click events.
There is code error inside show(). ReferenceError: Can't find variable: b
Once above issue is fixed and b[i] is replaced with b1, its working fine.
Please check below code snippet.
const b1 = document.getElementById("b1");
const btn = document.getElementById("btn");
let b1T = b1.innerText;
let xo = true;
show();
function show() {
for(let i = 0; i < 9; i++) {
b1.addEventListener("click",go)
}
}
//decide x or o is displayed
function go(event) {
if(xo) {
event.target.innerText = "X";
event.target.disabled = true;
xo = false;
} else {
event.target.innerText = "O";
event.target.disabled = true;
xo = true;
}
}
function decide() {
if(b1T === "X"){
//do something
}
}
<body>
<button id="b1">Click</button>
</body>
Let me know if this is what expected.
My solution is to create a dc variable to record how many buttons are pressed, and put the function decide() into function go(), and declare b1T inside the function decide() so that everytime I click the button it will update all the variables that store button.innertext.
Here's the code:
const b1 = document.getElementById("b1");
const btn = document.getElementById("btn");
let b1T = b1.innerText;
let dc = 0;
let xo = true;
show();
function show() {
for(let i = 0; i < 9; i++) {
b1.addEventListener("click",go)
}
}
//decide x or o is displayed
function go(event) {
if(xo) {
event.target.innerText = "X";
event.target.disabled = true;
dc += 1;
xo = false;
} else {
event.target.innerText = "O";
event.target.disabled = true;
dc+= 1;
xo = true;
}
decide();
}
function decide() {
let b1T = b1.innerText;
if(dc >= 5) {
if(b1T === "X"){
//do something
}
}
}
Thank all you guys' efforts
I developed a web application base on JavaScript, with Google Speech Recognizer API.
The main language should be Hebrew, and supposed to help doctors to write medical diagnosis.
The problem is that if I say medical word in English like C.T or Diabetes that in professional language should be say in English, it writes the English word in Hebrew.
My question is, if there is any option to define multi languages option or define languages priorities that when it detect unfamiliar word it will try the second choice????
Please help me Thank you!
This is my JavaScript Code:
var langs =
[['Afrikaans', ['af-ZA']],
['Hebrew', ['he-IL']],
['Bahasa Melayu', ['ms-MY']],
['Català', ['ca-ES']],
['Čeština', ['cs-CZ']],
['Deutsch', ['de-DE']],
['English', ['en-AU', 'Australia'],
['en-CA', 'Canada'],
['en-IN', 'India'],
['en-NZ', 'New Zealand'],
['en-ZA', 'South Africa'],
['en-GB', 'United Kingdom'],
['en-US', 'United States']],
['Español', ['es-AR', 'Argentina'],
['es-BO', 'Bolivia'],
['es-CL', 'Chile'],
['es-CO', 'Colombia'],
['es-CR', 'Costa Rica'],
['es-EC', 'Ecuador'],
['es-SV', 'El Salvador'],
['es-ES', 'España'],
['es-US', 'Estados Unidos'],
['es-GT', 'Guatemala'],
['es-HN', 'Honduras'],
['es-MX', 'México'],
['es-NI', 'Nicaragua'],
['es-PA', 'Panamá'],
['es-PY', 'Paraguay'],
['es-PE', 'Perú'],
['es-PR', 'Puerto Rico'],
['es-DO', 'República Dominicana'],
['es-UY', 'Uruguay'],
['es-VE', 'Venezuela']],
['Euskara', ['eu-ES']],
['Français', ['fr-FR']],
['Galego', ['gl-ES']],
['Hrvatski', ['hr_HR']],
['IsiZulu', ['zu-ZA']],
['Íslenska', ['is-IS']],
['Italiano', ['it-IT', 'Italia'],
['it-CH', 'Svizzera']],
['Magyar', ['hu-HU']],
['Nederlands', ['nl-NL']],
['Norsk bokmål', ['nb-NO']],
['Polski', ['pl-PL']],
['Português', ['pt-BR', 'Brasil'],
['pt-PT', 'Portugal']],
['Română', ['ro-RO']],
['Slovenčina', ['sk-SK']],
['Suomi', ['fi-FI']],
['Svenska', ['sv-SE']],
['Türkçe', ['tr-TR']],
['български', ['bg-BG']],
['Pусский', ['ru-RU']],
['Српски', ['sr-RS']],
['한국어', ['ko-KR']],
['中文', ['cmn-Hans-CN', '普通话 (中国大陆)'],
['cmn-Hans-HK', '普通话 (香港)'],
['cmn-Hant-TW', '中文 (台灣)'],
['yue-Hant-HK', '粵語 (香港)']],
['日本語', ['ja-JP']],
['Lingua latīna', ['la']]];
for (var i = 0; i < langs.length; i++) {
select_language.options[i] = new Option(langs[i][0], i);
}
select_language.selectedIndex = 1;
updateCountry();
select_dialect.selectedIndex = 1;
showInfo('info_start');
function updateCountry() {
for (var i = select_dialect.options.length - 1; i >= 0; i--) {
select_dialect.remove(i);
}
var list = langs[select_language.selectedIndex];
for (var i = 1; i < list.length; i++) {
select_dialect.options.add(new Option(list[i][1], list[i][0]));
}
select_dialect.style.visibility = list[1].length == 1 ? 'hidden' : 'visible';
}
var create_email = false;
var final_transcript = '';
var recognizing = false;
var ignore_onend;
var start_timestamp;
if (!('webkitSpeechRecognition' in window)) {
console.log("before upgrade")
upgrade();
} else {
start_button.style.display = 'inline-block';
var recognition = new webkitSpeechRecognition();
recognition.continuous = true;
recognition.interimResults = true;
recognition.onstart = function() {
recognizing = true;
showInfo('info_speak_now');
console.log("webkitSpeechRecognition")
start_img.src = '/static/Mic_MicroPhone_Mute.PNG';
start_pic=document.getElementById("start_img")
start_pic.style.height="59px";
start_pic.style.width="43px";
};
recognition.onerror = function(event) {
if (event.error == 'no-speech') {
console.log("event error");
start_img.src = '/static/mic.png';
showInfo('info_no_speech');
ignore_onend = true;
}
if (event.error == 'audio-capture') {
console.log("event caputre");
start_img.src = '/static/mic.png';
showInfo('info_no_microphone');
ignore_onend = true;
}
if (event.error == 'not-allowed') {
console.log("even not allowed");
if (event.timeStamp - start_timestamp < 100) {
showInfo('info_blocked');
} else {
showInfo('info_denied');
}
ignore_onend = true;
}
};
recognition.onend = function() {
recognizing = false;
if (ignore_onend) {
return;
}
console.log("init mic image");
start_img.src = '/static/mic.png';
if (!final_transcript) {
showInfo('info_start');
return;
}
showInfo('');
// if (window.getSelection) {
// window.getSelection().removeAllRanges();
// var range = document.createRange();
// range.selectNode(document.getElementById('final_span'));
// window.getSelection().addRange(range);
// }
if (create_email) {
create_email = false;
createEmail();
}
};
recognition.onresult = function(event) {
var interim_transcript = '';
for (var i = event.resultIndex; i < event.results.length; ++i) {
if (event.results[i].isFinal) {
console.log("Final!!!!!!!!!!!!")
console.log(final_span.value+event.results[i][0].transcript);
final_transcript = final_span.value+event.results[i][0].transcript;
final_span.value=final_transcript;
} else {
interim_transcript += event.results[i][0].transcript;
}
}
final_transcript = capitalize(final_transcript);
console.log("interim_transcript :");
console.log(interim_transcript);
console.log("final_transcript :");
console.log(final_transcript);
// final_span.value = linebreak(interim_transcript);
if (final_transcript) {
console.log("final transcript true");
// final_span.value= linebreak(final_transcript);
}
if (final_transcript || interim_transcript) {
showButtons('inline-block');
}
};
}
function upgrade() {
start_button.style.visibility = 'hidden';
showInfo('info_upgrade');
}
var two_line = /\n\n/g;
var one_line = /\n/g;
function linebreak(s) {
return s.replace(two_line, '<p></p>').replace(one_line, '<br>');
}
var first_char = /\S/;
function capitalize(s) {
return s.replace(first_char, function(m) { return m.toUpperCase(); });
}
function createEmail() {
var n = final_transcript.indexOf('\n');
if (n < 0 || n >= 80) {
n = 40 + final_transcript.substring(40).indexOf(' ');
}
var subject = encodeURI(final_transcript.substring(0, n));
var body = encodeURI(final_transcript.substring(n + 1));
textarea_value=document.getElementById("final_span").value;
window.location.href = 'mailto:?subject=' + "Puzzle-Soft Telemedicine - Speech Recognizer " + '&body=' + textarea_value;
}
function copyButton() {
if (recognizing) {
recognizing = false;
recognition.stop();
}
copy_button.style.display = 'none';
copy_info.style.display = 'inline-block';
showInfo('');
}
function emailButton() {
if (recognizing) {
create_email = true;
recognizing = false;
recognition.stop();
} else {
createEmail();
}
email_button.style.display = 'none';
email_info.style.display = 'inline-block';
showInfo('');
}
function startButton(event) {
if (recognizing) {
recognition.stop();
console.log("StartButton if")
return;
}
console.log("StartButton else")
final_transcript = '';
recognition.lang = select_dialect.value;
recognition.start();
ignore_onend = false;
// final_span.innerHTML = '';
// interim_span.innerHTML = '';
start_img.src = '/static/mic.png';
showInfo('info_allow');
showButtons('none');
start_timestamp = event.timeStamp;
}
function showInfo(s) {
if (s) {
for (var child = info.firstChild; child; child = child.nextSibling) {
if (child.style) {
child.style.display = child.id == s ? 'inline' : 'none';
}
}
info.style.visibility = 'visible';
} else {
info.style.visibility = 'hidden';
}
}
var current_style;
function showButtons(style) {
if (style == current_style) {
return;
}
current_style = style;
copy_button.style.display = style;
email_button.style.display = style;
copy_info.style.display = 'none';
email_info.style.display = 'none';
}
function ClearText() {
console.log("clear");
text_area_value=document.getElementById("final_span");
console.log(text_area_value);
console.log(text_area_value.value);
text_area_value.value='';
}
//var givevalue = function (my_key) {
// return dict[my_key];
//
// }
//
//js_json={'אדרנלypr': 'Olanzapine Teva', 'זיפאדהרה': 'Zypadhera', 'אומפראזול': 'Omeprazole', 'אומפרדקס': 'Omepradex', 'לוסק': 'Losec', 'אומפריקס': 'Omeprix', 'אומפרדקס Z': 'Omepradex Z', 'אומפרה': 'Omepra', 'אונדאנסטרון': 'Ondansetron', 'זופרן': 'Zofran', 'אודנטרון': 'Odnatron', 'אונדאנסטרון - פרזניוס': 'Ondansetron - Fresenius', 'אונדנסטרון אינובמד': 'Ondansetron Inovamed'}
//function replaceTextAreaDict() {
//textarea_result=document.getElementById("final_span");
// textarea_words=textarea_result.split(' ') ;
// for (var i = 0; i < textarea_result.length; i++) {
//
// }
//
//
//
// givevalue()
//
//}
//
//replaceTextAreaDict();
You cannot mix language.
Speech Recognition roughly contains 3 part -> Accoustic model, Language model, and dictionary.
Accoustic model is the result of data training contains relationship between audio signal and phonetic
Dictionary contains words and how they pronounced, for e.g, word TOP are pronounced "T AH P" on the general speech recognition dictionary.
Language model is the connection between words to create sentences, for e.g. the word "I" is connected with "am", so the speech recognizer will very rarely (or never) give the result of "I are" or "I is".
Every Language have their own Accoustic Model (phonetic), Dictionary (words), and Language Model (sentences), so we can just mix them up.
The Question is : Is it still possible?
The Answer is : YES!
You can build your own language (in this case Medical language) using many tools, one I already tried called CMU Sphinx / Pocket Sphinx. You can build your own model, train it, and make a dictionary out of it. It will be alot work to do, but you can configure anything you will need for speech recognition.
Link for any platform implementation : https://github.com/cmusphinx
I found, that speech recognition API duplicates result phrases on my Android (and does not duplicate on desktop).
For each phrase said, it returns two results. First one is
and the second one is
As you see, in the second return, phrase is duplicated, each copy is marked as final and second one is beyond resultIndex. In first return there is only one copy, it is final and it is beyond resultIndex.
I would take only second return, but the problem is that it happens on mobile Chrome, but does not happen on desktop Chrome. Desktop Chrome returns only first return.
So, the question is: is this by design behavior? Then how to distinguish single final phrase then commonly for all computers?
Or may be this is some error like sound echo, then the question is how to avoid/check echo?
UPDATE
Html is follows:
<input id="recbutton" type="button" value="Recognize">
<div id="output">
<div>
Initial text
</div>
</div>
Code is follows:
var recognition = null;
var recognitionStarted = false;
var printcount = 1;
var lastPhrase = null;
$(function() {
attachRecognition();
});
$('#recbutton').click( function() {
if( !recognitionStarted ) {
recognition.start();
}
else {
recognition.stop();
}
});
function printOut(text) {
var id = 'printcount' + printcount;
printcount++;
$('#output').append(
"<div id='" + printcount + "'>" + text + "</div>"
);
$("#output").animate({ scrollTop: $("#output").prop('scrollHeight')});
return printcount;
}
function attachRecognition() {
if (!('webkitSpeechRecognition' in window)) {
$('button').prop('disabled', true);
recognition = null;
} else {
$('button').prop('disabled', false);
recognition = new webkitSpeechRecognition();
recognition.continuous = true;
recognition.interimResults = true;
recognition.lang = "en-US";
recognition.onstart = function(event) {
recognitionStarted = true;
printOut("speech recognition started");
};
recognition.onend = function(event) {
recognitionStarted = false;
printOut("speech recognition stopped");
};
recognition.onresult = function(event) {
var finalPhrase = '';
var interimPhrase = '';
var result;
var printcount;
for(var i=0; i<event.results.length; ++i) {
result = event.results[i];
if( result.isFinal ) {
finalPhrase = finalPhrase.trim() + ' ' + result[0].transcript;
}
else {
interimPhrase = interimPhrase.trim() + ' ' + result[0].transcript;
}
}
if( !lastPhrase ) {
printcount = printOut('');
lastPhrase = $('#' + printcount);
}
lastPhrase.html(finalPhrase.trim() + ' ' + interimPhrase.trim());
if( finalPhrase.trim() ) {
lastPhrase = null;
}
};
}
}
JsFiddle: https://jsfiddle.net/dimskraft/envwao8o/1/
The results provided on Chrome mobile regarding the result.isFinal property seem to have a bug or in any case to differ from the ones on Chrome desktop. A possible workaround is to check the confidence attribute of the (first) alternative:
onResultHandler(event) {
let i = event.resultIndex;
let result = event.results[i];
let isFinal = result.isFinal && (result[0].confidence > 0);
}
It also looks like that sometimes the final result is emitted twice (with the same confidence value), in that case you may want to debounce it or just process the first event, like this:
if (isFinal) {
transcript = result[0].transcript;
if(transcript == lastDebounceTranscript) {
return;
}
lastDebounceTranscript = transcript;
}
where lastDebounceTranscript is a variable that you initialize outside of the scope of the event handler
Try this:
recognition.continuous = false;
recognition.interimResults = false;
recognition.maxAlternatives = 1;
JSFiddle: https://jsfiddle.net/envwao8o/4/
I'm experimenting with javascript programs and I hit a snag. The program suddenly lags my browser (infinite loop maybe), dunno why.
function fullscreen() {
if (document.body.requestFullScreen) {document.body.requestFullScreen();}
else if (document.body.webkitRequestFullScreen) {document.body.webkitRequestFullScreen();}
else if (document.body.mozRequestFullScreen) {document.body.mozRequestFullScreen();}
}
var bash = document.createElement('span');
bash.setAttribute('id', 'bash');
document.body.appendChild(bash);
var cursor = document.createElement('span');
cursor.setAttribute('id', 'bashCursor');
cursor.textContent = '_';
cursor.style.display = 'none';
cursor.style.fontWeight = 'bold';
document.body.appendChild(cursor);
window.Bash = {};
window.Bash.printing = false;
window.Bash.queue = Array();
window.Bash.span = bash;
window.Bash.span.cursor = cursor;
delete bash; delete bash;
function bashPrint() {
window.Bash.writing = true;
var bash = window.Bash.span
var i;
while (window.Bash.queue.length) {
if (window.Bash.queue[0] == undefined) {
i = 0;
while (i < window.Bash.queue.length) {
window.Bash.queue[i] = window.Bash.queue[i+1];
console.log('l:'+window.Bash.queue.length);
console.log(window.Bash.queue);
delete window.Bash.queue[i+1];
window.Bash.queue.splice(i,1);
i++;
}
} else if (window.Bash.queue[0]['type'] == 'instant') {
bash.textContent += window.Bash.queue[0]['value'];
delete window.Bash.queue[0];
window.Bash.queue.splice(0,1);
} else if (window.Bash.queue[0]['type'] == 'wait') {
setTimeout(bashPrintWaiting, window.Bash.queue[0]['wait']);
break;
} else if (window.Bash.queue[0]['type'] == 'cursor') {
if (window.Bash.queue[0]['value']) {
window.Bash.span.cursor.style.display = 'inline';
} else {
window.Bash.span.cursor.style.display = 'none';
}
}
}
window.Bash.writing = false;
}
function bashPrintWaiting() {
window.Bash.writing = true;
var bash = window.Bash.span;
bash.textContent += window.Bash.queue[0]['value'];
delete window.Bash.queue[0];
window.Bash.queue.splice(0,1);
window.Bash.writing = false;
setTimeout(bashPrint, 0);
}
function bashWrite(string) {
var array = Array();
array['type'] = 'instant';
array['value'] = string;
window.Bash.queue[window.Bash.queue.length] = array
}
function bashPause(times, string) {
if (!string) {string='';}
while (times > 0) {
var array = Array();
array['type'] = 'wait';
array['value'] = string;
array['wait'] = 50 + Math.floor(Math.random()*450);
window.Bash.queue[window.Bash.queue.length] = array;
times--;
}
}
function bashCursor(enabled) {
var array = Array();
array['type'] = 'cursor';
array['value'] = enabled;
window.Bash.queue[window.Bash.queue.length] = array;
}
bashWrite('Uncompressing');
bashPause(12, '.');
bashWrite('OK\n');
bashPause(3);
bashWrite('Build v. 0.1.01-release (x86_64-pc)\n');
bashPause(2);
bashWrite('Connecting');
bashPause(35, '.');
bashWrite('Error, unknown user. See connect.log for futher information.\n');
bashPause(2);
bashWrite('none#m ~ $ >>');
bashCursor(true);
bashPrint();
I uploaded it on jsFiddle - http://jsfiddle.net/uQcCP/
Program freezes between:
bashWrite('Error, unknown user. See connect.log for futher information.\n');
and
bashPause(2);
Please, can you help me? Thanks a lot.
The infinite loop starts on line 51: while (window.Bash.queue.length) {
It then ends up in the if statement on line 74, and within this the queue is never shortened:
else if (window.Bash.queue[0]['type'] == 'cursor') {
if (window.Bash.queue[0]['value']) {
window.Bash.span.cursor.style.display = 'inline';
If you find yourself having infinite loop problems in Chrome, open up your development tools and go to the script tab before you open up the page. After you open up the page and it starts looping, you can click the pause button to throw a breakpoint wherever the code is currently executing. From there it's a lot easier to divine where you're getting your error.
I have a for loop that goes through each input with class="required" , and it its empty it changes its background color. Also, it adds a message to part of the page: "Fields with red background color are required". But, I only want the message to be displayed once. Even if 5 fields are empty, only one message should be displayed. Any suggestions?
Heres my code:
<script type="text/javascript" >
window.onload = function() {
document.getElementById("formID").onsubmit = function() {
var fields = this.getElementsByClassName("validate"),
sendForm = true;
for(var i = 0; i < fields.length; i++) {
if(!fields[i].value) {
fields[i].style.backgroundColor = "#ffb8b8";
var inst = document.getElementById('inst');
var reason = inst.insertRow(-1);
var cell1=reason.insertCell(0);
cell1.innerHTML = '<p>Fields with a red background are required and empty. Please fill them in and try resubmitting. Thanks.</p>';
inst.appendChild(reason);
sendForm = false;
}
else {
fields[i].style.backgroundColor = "#fff";
}
}
if(!sendForm) {
return false;
}
}
}
</script>
You could have a flag that gets set to true any time a field fails validation. After the execution of the loop, if the flag is true, append the error message.
Well this should be rather simple - you've already got a boolean variable to say whether the validation has failed - sendForm. So just take the "append message" part out of the loop and into the if.
document.getElementById("formID").onsubmit = function() {
var fields = this.getElementsByClassName("validate"),
sendForm = true;
for(var i = 0; i < fields.length; i++) {
if(!fields[i].value) {
fields[i].style.backgroundColor = "#ffb8b8";
sendForm = false;
}
else {
fields[i].style.backgroundColor = "#fff";
}
}
if(!sendForm) {
var inst = document.getElementById('inst');
var reason = inst.insertRow(-1);
var cell1=reason.insertCell(0);
cell1.innerHTML = '<p>Fields with a red background are required and empty. Please fill them in and try resubmitting. Thanks.</p>';
inst.appendChild(reason);
return false;
}
}
Use a flag initialize it to false and once u get any empty field make it true and print the message only if flag is false. Here
<script type="text/javascript" >
window.onload = function() {
document.getElementById("formID").onsubmit = function() {
var fields = this.getElementsByClassName("validate"),
sendForm = true;
var flag=false;
for(var i = 0; i < fields.length; i++) {
if(!fields[i].value) {
fields[i].style.backgroundColor = "#ffb8b8";
if(flag==false) {
var inst = document.getElementById('inst');
var reason = inst.insertRow(-1);
var cell1=reason.insertCell(0);
cell1.innerHTML = '<p>Fields with a red background are required and empty. Please fill them in and try resubmitting. Thanks.</p>';
inst.appendChild(reason);
}
flag=true;
sendForm = false;
}
else {
fields[i].style.backgroundColor = "#fff";
}
}
if(!sendForm) {
return false;
}
}
}
</script>
add a boolean flag to indicate that you have already displayed the message
window.onload = function() {
var notified = false;
for(var i = 0; i < fields.length; i++) {
if(!fields[i].value) {
fields[i].style.backgroundColor = "#ffb8b8";
...
if (!notified) {
cell1.innerHTML = '<p>Fields with a red background are required and empty. Please fill them in and try resubmitting. Thanks.</p>';
inst.appendChild(reason);
notified = true;
}
....
}