v66: слоги через DOM+onmouseover/onclick — надёжнее innerHTML
This commit is contained in:
Vendored
+20
-8
@@ -628,18 +628,30 @@ async function doCompare(blob, originalText, duration) {
|
|||||||
'<span>🗣 Артикуляция: ' + phon.voiceClarity + '%</span>' +
|
'<span>🗣 Артикуляция: ' + phon.voiceClarity + '%</span>' +
|
||||||
'</div>';
|
'</div>';
|
||||||
|
|
||||||
// Слоги — кликабельные
|
// Слоги — кликабельные (DOM-элементы, не innerHTML)
|
||||||
_currentBlob = blob;
|
_currentBlob = blob;
|
||||||
_currentSylBuf = null;
|
_currentSylBuf = null;
|
||||||
const sy = syllabifyIT(originalText);
|
const sy = syllabifyIT(originalText);
|
||||||
if (sy && sy.includes('-')) {
|
if (sy && sy.includes('-')) {
|
||||||
const syls = sy.split('-');
|
const syls = sy.split('-');
|
||||||
const sylHTML = '<div style="margin-top:8px;font-size:1.2em;letter-spacing:2px">' +
|
const div = document.createElement('div');
|
||||||
syls.map((s, i) =>
|
div.style.cssText = 'margin-top:8px;font-size:1.2em;letter-spacing:2px;user-select:none';
|
||||||
'<span class="syl-chip" onclick="playSyllable(' + i + ',' + syls.length + ')">' + s + '</span>'
|
syls.forEach((s, i) => {
|
||||||
).join('<span style="color:#ccc">·</span>') +
|
if (i > 0) {
|
||||||
'</div>';
|
const sep = document.createElement('span');
|
||||||
document.getElementById('diff').innerHTML += sylHTML;
|
sep.style.cssText = 'color:#ccc;margin:0 1px';
|
||||||
|
sep.textContent = '·';
|
||||||
|
div.appendChild(sep);
|
||||||
|
}
|
||||||
|
const chip = document.createElement('span');
|
||||||
|
chip.textContent = s;
|
||||||
|
chip.style.cssText = 'cursor:pointer;padding:2px 4px;border-radius:4px;transition:background 0.15s';
|
||||||
|
chip.onmouseover = () => { chip.style.background = '#e0e0ff'; };
|
||||||
|
chip.onmouseout = () => { chip.style.background = ''; };
|
||||||
|
chip.onclick = () => { chip.style.background = '#b0b0ff'; setTimeout(() => { chip.style.background = '#e0e0ff'; }, 150); playSyllable(i, syls.length); };
|
||||||
|
div.appendChild(chip);
|
||||||
|
});
|
||||||
|
document.getElementById('diff').appendChild(div);
|
||||||
}
|
}
|
||||||
|
|
||||||
setStatus('Готово.');
|
setStatus('Готово.');
|
||||||
@@ -651,7 +663,7 @@ async function doCompare(blob, originalText, duration) {
|
|||||||
<script>
|
<script>
|
||||||
// ---------- Глобальные переменные и инициализация ----------
|
// ---------- Глобальные переменные и инициализация ----------
|
||||||
const GROQ_API_KEY = '';
|
const GROQ_API_KEY = '';
|
||||||
const VERSION = 'v65';
|
const VERSION = 'v66';
|
||||||
|
|
||||||
let mediaRecorder, audioChunks = [], userAudioBlob = null, ttsText = '';
|
let mediaRecorder, audioChunks = [], userAudioBlob = null, ttsText = '';
|
||||||
let isRecording = false, isAnalyzing = false, micAnalyser = null, micAnimId = null;
|
let isRecording = false, isAnalyzing = false, micAnalyser = null, micAnimId = null;
|
||||||
|
|||||||
+19
-7
@@ -99,18 +99,30 @@ async function doCompare(blob, originalText, duration) {
|
|||||||
'<span>🗣 Артикуляция: ' + phon.voiceClarity + '%</span>' +
|
'<span>🗣 Артикуляция: ' + phon.voiceClarity + '%</span>' +
|
||||||
'</div>';
|
'</div>';
|
||||||
|
|
||||||
// Слоги — кликабельные
|
// Слоги — кликабельные (DOM-элементы, не innerHTML)
|
||||||
_currentBlob = blob;
|
_currentBlob = blob;
|
||||||
_currentSylBuf = null;
|
_currentSylBuf = null;
|
||||||
const sy = syllabifyIT(originalText);
|
const sy = syllabifyIT(originalText);
|
||||||
if (sy && sy.includes('-')) {
|
if (sy && sy.includes('-')) {
|
||||||
const syls = sy.split('-');
|
const syls = sy.split('-');
|
||||||
const sylHTML = '<div style="margin-top:8px;font-size:1.2em;letter-spacing:2px">' +
|
const div = document.createElement('div');
|
||||||
syls.map((s, i) =>
|
div.style.cssText = 'margin-top:8px;font-size:1.2em;letter-spacing:2px;user-select:none';
|
||||||
'<span class="syl-chip" onclick="playSyllable(' + i + ',' + syls.length + ')">' + s + '</span>'
|
syls.forEach((s, i) => {
|
||||||
).join('<span style="color:#ccc">·</span>') +
|
if (i > 0) {
|
||||||
'</div>';
|
const sep = document.createElement('span');
|
||||||
document.getElementById('diff').innerHTML += sylHTML;
|
sep.style.cssText = 'color:#ccc;margin:0 1px';
|
||||||
|
sep.textContent = '·';
|
||||||
|
div.appendChild(sep);
|
||||||
|
}
|
||||||
|
const chip = document.createElement('span');
|
||||||
|
chip.textContent = s;
|
||||||
|
chip.style.cssText = 'cursor:pointer;padding:2px 4px;border-radius:4px;transition:background 0.15s';
|
||||||
|
chip.onmouseover = () => { chip.style.background = '#e0e0ff'; };
|
||||||
|
chip.onmouseout = () => { chip.style.background = ''; };
|
||||||
|
chip.onclick = () => { chip.style.background = '#b0b0ff'; setTimeout(() => { chip.style.background = '#e0e0ff'; }, 150); playSyllable(i, syls.length); };
|
||||||
|
div.appendChild(chip);
|
||||||
|
});
|
||||||
|
document.getElementById('diff').appendChild(div);
|
||||||
}
|
}
|
||||||
|
|
||||||
setStatus('Готово.');
|
setStatus('Готово.');
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
// ---------- Глобальные переменные и инициализация ----------
|
// ---------- Глобальные переменные и инициализация ----------
|
||||||
const GROQ_API_KEY = '';
|
const GROQ_API_KEY = '';
|
||||||
const VERSION = 'v65';
|
const VERSION = 'v66';
|
||||||
|
|
||||||
let mediaRecorder, audioChunks = [], userAudioBlob = null, ttsText = '';
|
let mediaRecorder, audioChunks = [], userAudioBlob = null, ttsText = '';
|
||||||
let isRecording = false, isAnalyzing = false, micAnalyser = null, micAnimId = null;
|
let isRecording = false, isAnalyzing = false, micAnalyser = null, micAnimId = null;
|
||||||
|
|||||||
Reference in New Issue
Block a user