javascript - Javascript 使事件点击和语音识别与多个按钮一起工作
问题描述
所以我正在使用 webkitSpeechRecognition 并且效果很好,但问题是我想同时在多个地方使用它,当我将它添加到我页面上的另一个部分时它不能正常工作。
这是它自己工作的:
var final_transcript = '';
var recognizing = false;
var ignore_onend;
var start_timestamp;
//get languages
// https://gist.githubusercontent.com/onigetoc/d5dc63320c4d08633eb7b7daf6c1ddeb/raw/e9c3da4a40db8edf4992db9219526617da811c4c/lang.json
$.get("//raw.githubusercontent.com/the-creature/language-json/master/data.json", function(data) {
var cList = $('#language');
var data = $.parseJSON(data);
$.each(data, function(i) {
var option = $('<option/>')
.attr('value', data[i].code)
.html(data[i].name)
.appendTo(cList);
});
var userLang = navigator.language || navigator.userLanguage;
$("#language").val(userLang);
});
// Speech Recognition
if (!('webkitSpeechRecognition' in window)) {
message.innerHTML = 'Web Speech API is not supported by this browser. Upgrade to <a href="//www.google.com/chrome">Chrome</a> version 25 or later.';
} else {
var recognition = new webkitSpeechRecognition();
recognition.continuous = true;
recognition.interimResults = true;
recognition.onstart = function() {
recognizing = true;
message.innerHTML = 'Speak now.';
talk_button.innerHTML = 'Listen';
};
recognition.onresult = function(event) {
var interim_transcript = '';
for (var i = event.resultIndex; i < event.results.length; ++i) {
if (event.results[i].isFinal) {
final_transcript += event.results[i][0].transcript;
vc_search(final_transcript);
} else {
interim_transcript += event.results[i][0].transcript;
}
}
final_span.innerHTML = final_transcript;
interim_span.innerHTML = interim_transcript;
};
recognition.onend = function() {
recognizing = false;
if (ignore_onend) {
return;
}
speechMyText(final_transcript);
if (!final_transcript) {
message.innerHTML = 'Click "Talk" and begin speaking.';
talk_button.innerHTML = 'Talk';
return;
}
};
recognition.onerror = function(event) {
if (event.error == 'no-speech') {
message.innerHTML = 'No speech was detected.';
ignore_onend = true;
}
if (event.error == 'audio-capture') {
message.innerHTML = 'No microphone was found. Ensure that a microphone is installed.';
ignore_onend = true;
}
if (event.error == 'not-allowed') {
if (event.timeStamp - start_timestamp < 100) {
message.innerHTML = 'Permission to use microphone is blocked. To change, go to chrome://settings/contentExceptions#media-stream';
} else {
message.innerHTML = 'Permission to use microphone was denied.';
}
ignore_onend = true;
}
};
}
function talkWithApp(event) {
if (recognizing) {
recognition.stop();
message.innerHTML = 'Click "Talk" and begin speaking.';
talk_button.innerHTML = 'Talk';
return;
}
final_transcript = '';
recognition.lang = language.value;
recognition.start();
ignore_onend = false;
final_span.innerHTML = '';
interim_span.innerHTML = '';
message.innerHTML = 'Click the "Allow" button above to enable your microphone.';
start_timestamp = event.timeStamp;
}
// Speech Synthesis
function speechMyText(textToSpeech) {
var u = new SpeechSynthesisUtterance();
u.text = textToSpeech;
u.lang = language.value;
u.rate = 1.0;
u.onend = function(event) {}
speechSynthesis.speak(u);
}
.message {
color:#999;
padding: 1em 0;
}
.todo, .response {
min-height:50px;
background-color: #fff;
margin-bottom: 0.5em;
padding: 1px;
color:#555;
-webkit-box-shadow: 0 0px 3px #BDBDBD;
box-shadow: 0 0px 3px #BDBDBD;
transition: all 0.3s ease-in-out;
}
<div class="container">
<div id="message" class="message">Click "Talk" and begin speaking.</div>
<div class="todo"> <span id="final_span" class="final"></span>
<span id="interim_span" class="interim"></span>
</div>
<div class="controls">
<button id="talk_button" type="button" class="btn btn-default" onclick="talkWithApp(event)">Talk</button>
<select id="language" class="select">
<option selected="selected">Select Your Language</option>
</select>
</div>
</div>
这是它在同一页面内多次运行:
var final_transcript = '';
var recognizing = false;
var ignore_onend;
var start_timestamp;
//get languages
// https://gist.githubusercontent.com/onigetoc/d5dc63320c4d08633eb7b7daf6c1ddeb/raw/e9c3da4a40db8edf4992db9219526617da811c4c/lang.json
$.get("//raw.githubusercontent.com/the-creature/language-json/master/data.json", function(data) {
var cList = $('#language');
var data = $.parseJSON(data);
$.each(data, function(i) {
var option = $('<option/>')
.attr('value', data[i].code)
.html(data[i].name)
.appendTo(cList);
});
var userLang = navigator.language || navigator.userLanguage;
$("#language").val(userLang);
});
// Speech Recognition
if (!('webkitSpeechRecognition' in window)) {
message.innerHTML = 'Web Speech API is not supported by this browser. Upgrade to <a href="//www.google.com/chrome">Chrome</a> version 25 or later.';
} else {
var recognition = new webkitSpeechRecognition();
recognition.continuous = true;
recognition.interimResults = true;
recognition.onstart = function() {
recognizing = true;
message.innerHTML = 'Speak now.';
talk_button.innerHTML = 'Listen';
};
recognition.onresult = function(event) {
var interim_transcript = '';
for (var i = event.resultIndex; i < event.results.length; ++i) {
if (event.results[i].isFinal) {
final_transcript += event.results[i][0].transcript;
vc_search(final_transcript);
} else {
interim_transcript += event.results[i][0].transcript;
}
}
final_span.innerHTML = final_transcript;
interim_span.innerHTML = interim_transcript;
};
recognition.onend = function() {
recognizing = false;
if (ignore_onend) {
return;
}
speechMyText(final_transcript);
if (!final_transcript) {
message.innerHTML = 'Click "Talk" and begin speaking.';
talk_button.innerHTML = 'Talk';
return;
}
};
recognition.onerror = function(event) {
if (event.error == 'no-speech') {
message.innerHTML = 'No speech was detected.';
ignore_onend = true;
}
if (event.error == 'audio-capture') {
message.innerHTML = 'No microphone was found. Ensure that a microphone is installed.';
ignore_onend = true;
}
if (event.error == 'not-allowed') {
if (event.timeStamp - start_timestamp < 100) {
message.innerHTML = 'Permission to use microphone is blocked. To change, go to chrome://settings/contentExceptions#media-stream';
} else {
message.innerHTML = 'Permission to use microphone was denied.';
}
ignore_onend = true;
}
};
}
function talkWithApp(event) {
if (recognizing) {
recognition.stop();
message.innerHTML = 'Click "Talk" and begin speaking.';
talk_button.innerHTML = 'Talk';
return;
}
final_transcript = '';
recognition.lang = language.value;
recognition.start();
ignore_onend = false;
final_span.innerHTML = '';
interim_span.innerHTML = '';
message.innerHTML = 'Click the "Allow" button above to enable your microphone.';
start_timestamp = event.timeStamp;
}
// Speech Synthesis
function speechMyText(textToSpeech) {
var u = new SpeechSynthesisUtterance();
u.text = textToSpeech;
u.lang = language.value;
u.rate = 1.0;
u.onend = function(event) {}
speechSynthesis.speak(u);
}
.message {
color:#999;
padding: 1em 0;
}
.todo, .response {
min-height:50px;
background-color: #fff;
margin-bottom: 0.5em;
padding: 1px;
color:#555;
-webkit-box-shadow: 0 0px 3px #BDBDBD;
box-shadow: 0 0px 3px #BDBDBD;
transition: all 0.3s ease-in-out;
}
<div class="container">
<div id="message" class="message">Click "Talk" and begin speaking.</div>
<div class="todo"> <span id="final_span" class="final"></span>
<span id="interim_span" class="interim"></span>
</div>
<div class="controls">
<button id="talk_button" type="button" class="btn btn-default" onclick="talkWithApp(event)">Talk</button>
<select id="language" class="select">
<option selected="selected">Select Your Language</option>
</select>
</div>
</div>
<div class="container">
<div id="message" class="message">Click "Talk" and begin speaking.</div>
<div class="todo"> <span id="final_span" class="final"></span>
<span id="interim_span" class="interim"></span>
</div>
<div class="controls">
<button id="talk_button" type="button" class="btn btn-default" onclick="talkWithApp(event)">Talk</button>
<select id="language" class="select">
<option selected="selected">Select Your Language</option>
</select>
</div>
</div>
正如您所看到的,它在多次运行时都无法正常工作。我怎样才能使它只使用被点击的部分?但仍然适用于页面上的多个位置。
以下是两种不同的方式:
解决方案
似乎在您的 HTML 中您多次使用 ID;ID 对于某个页面或框架应该是唯一的。
然后在您的脚本中,识别对象和您的事件都无法正确获取和分配值,因为他们尝试访问的 ID 已被多次声明。
我所做的是;
删除所有 ID 以使用类
添加全局
var activeButton
将talk事件绑定到整个文档并在
.talk_button
单击时触发。单击时
.talk_button
,将围绕该按钮设置上下文。这是用activeButton = $(this);
. 您会注意到我使用了.parent()
,的组合.find()
来查找该按钮的上下文或容器中的元素。
在 jsfiddle 上运行演示。使用起来很有趣,不知道浏览器上有现成的语音 api。
推荐阅读
- pandas - ValueError:使用curve_fit()时,操作数无法与形状(38563,54)(38563,)一起广播
- powershell - 如何使用 Select-Object、Where-Object 在哈希表中获取正确的值
- c# - 无法读取大于 2gb 的视频文件
- php - 字段“activation_token”没有默认值
- c# - 如何通过 Web API 上传音频文件?
- django - Heroku 上的 Django:ModuleNotFoundError:没有名为“app_name”的模块
- mysql - 如果它们对同一个人 ID 重复,我需要在不同列中显示行值
- html - 创建具有相同布局*每行*的 flexbox 行
- javascript - Apollo - 将客户端链接到多个 graphql 模式注册表
- optimization - 自动优化和谷歌洞察