From 40782435fefd831f47ad973663e55ef8112ec2fd Mon Sep 17 00:00:00 2001 From: guoqingshan Date: Sun, 2 Aug 2026 22:37:29 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=89=93=E5=AD=97=E7=BB=83=E4=B9=A0?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E8=87=AA=E5=8A=A8=E6=9C=97=E8=AF=BB=E4=B8=8E?= =?UTF-8?q?=E9=80=89=E5=8C=BA=E6=9C=97=E8=AF=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- typing.css | 6 ++++++ typing.html | 1 + typing.js | 41 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+) diff --git a/typing.css b/typing.css index 504606d..07c1277 100644 --- a/typing.css +++ b/typing.css @@ -94,6 +94,12 @@ gap: 0.5rem; margin-left: auto; } +#btn-typing-speak { + width: 36px; + padding-left: 0; + padding-right: 0; + text-align: center; +} .type-toolbar button { background: none; border: 1px solid var(--border); diff --git a/typing.html b/typing.html index b7f1f07..654d242 100644 --- a/typing.html +++ b/typing.html @@ -53,6 +53,7 @@
+
diff --git a/typing.js b/typing.js index 54d3528..3dc408d 100644 --- a/typing.js +++ b/typing.js @@ -6,6 +6,7 @@ var typed = ''; var typingStartedAt = 0; var typingFinished = false; var typingSession = { mode: '', categoryId: '', categoryName: '', itemCount: 0 }; +var typingSelectionTimer = null; var KEY_ROWS = [ [ @@ -195,6 +196,7 @@ function renderPractice() { } var item = typingItems[typingIndex]; var target = item.es; + speakText(item.es, 'es'); var targetHtml = ''; for (var i = 0; i < target.length; i++) { var ch = escTyping(target[i]); @@ -312,6 +314,35 @@ function showSetupView() { loadTypingLogs(); } +function readCurrentTarget() { + var item = typingItems[typingIndex]; + if (item && item.es) speakText(item.es, 'es'); +} + +function getTypingSelectedSpanish() { + var input = document.getElementById('typing-input'); + if (document.activeElement === input && input.selectionStart !== input.selectionEnd) { + return input.value.substring(input.selectionStart, input.selectionEnd).trim(); + } + var selection = window.getSelection(); + if (!selection || selection.isCollapsed || !selection.toString().trim()) return ''; + var node = selection.anchorNode; + var container = node && node.nodeType === 3 ? node.parentNode : node; + var target = document.getElementById('target-text'); + return container && target && target.contains(container) + ? selection.toString().trim() + : ''; +} + +function handleTypingSelection() { + var text = getTypingSelectedSpanish(); + if (!text || !typingItems[typingIndex]) return; + if (typingSelectionTimer) clearTimeout(typingSelectionTimer); + typingSelectionTimer = setTimeout(function() { + speakText(text, 'es'); + }, 150); +} + function renderKeyboard(target) { var next = target[typed.length] || ''; var press = keyPressForChar(next); @@ -422,7 +453,17 @@ document.getElementById('btn-start').addEventListener('click', startTyping); document.getElementById('btn-restart').addEventListener('click', startTyping); document.getElementById('btn-choose').addEventListener('click', showSetupView); document.getElementById('btn-refresh-records').addEventListener('click', loadTypingLogs); +document.getElementById('btn-typing-speak').addEventListener('click', readCurrentTarget); document.getElementById('typing-input').addEventListener('input', handleTypingInput); +document.getElementById('typing-input').addEventListener('mouseup', handleTypingSelection); +document.getElementById('typing-input').addEventListener('keyup', handleTypingSelection); +document.addEventListener('selectionchange', handleTypingSelection); +document.addEventListener('keydown', function(e) { + if (e.key === 'F6') { + e.preventDefault(); + readCurrentTarget(); + } +}); renderCategories(); loadTypingLogs();