v66: слоги через DOM+onmouseover/onclick — надёжнее innerHTML

This commit is contained in:
“Naeel”
2026-05-22 18:52:10 +04:00
parent abb943dd52
commit 77a75235ad
3 changed files with 40 additions and 16 deletions
+20 -8
View File
@@ -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
View File
@@ -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
View File
@@ -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;