-m "Falsche Zeichen werden in Gelb angezeigt."
This commit is contained in:
parent
562d9b48bc
commit
5a2d3e2167
3 changed files with 217 additions and 163 deletions
|
|
@ -4,6 +4,38 @@ body {
|
|||
transition: background-color 0.3s, color 0.3s;
|
||||
}
|
||||
|
||||
/* Cursor-Styling */
|
||||
.cursor-char {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.cursor-char::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: -3px;
|
||||
width: 100%;
|
||||
height: 3px;
|
||||
background-color: #0056b3;
|
||||
animation: blink 0.7s infinite;
|
||||
}
|
||||
|
||||
@keyframes blink {
|
||||
0%, 100% {
|
||||
opacity: 1;
|
||||
}
|
||||
50% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Dark Theme Anpassungen für Cursor */
|
||||
[data-bs-theme="dark"] .cursor-char::after {
|
||||
background-color: #0cf;
|
||||
height: 3px;
|
||||
animation: blink 0.7s infinite;
|
||||
}
|
||||
|
||||
/* Dark Theme Styles */
|
||||
[data-bs-theme="dark"] {
|
||||
--bs-body-bg: #121212;
|
||||
|
|
@ -64,6 +96,10 @@ body {
|
|||
color: #f87171; /* Helleres Rot für besseren Kontrast */
|
||||
}
|
||||
|
||||
[data-bs-theme="dark"] .incorrect-char-overlay {
|
||||
color: #ffc107;
|
||||
}
|
||||
|
||||
[data-bs-theme="dark"] .highlight-space,
|
||||
[data-bs-theme="dark"] .highlight-tab,
|
||||
[data-bs-theme="dark"] .highlight-newline {
|
||||
|
|
@ -80,7 +116,7 @@ body {
|
|||
background-color: #2d2d2d;
|
||||
color: #e0e0e0;
|
||||
border-color: #0d6efd;
|
||||
box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
|
||||
box-shadow: 0 0 0 0.25rem rgb(13 110 253 / 25%);
|
||||
}
|
||||
|
||||
[data-bs-theme="dark"] .lesson-link:hover {
|
||||
|
|
@ -103,14 +139,16 @@ body {
|
|||
|
||||
/* Fortschritt und Statistik Link Styling */
|
||||
.progress-toggle,
|
||||
.statistics-link {
|
||||
.statistics-link,
|
||||
.input-toggle {
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.progress-toggle:hover,
|
||||
.statistics-link:hover {
|
||||
.statistics-link:hover,
|
||||
.input-toggle:hover {
|
||||
color: #ffc107 !important;
|
||||
text-shadow: 0 0 10px #ffc107, 0 0 20px #ffc107;
|
||||
transform: scale(1.05);
|
||||
|
|
@ -137,14 +175,15 @@ body {
|
|||
line-height: 1.6;
|
||||
letter-spacing: 0.5px;
|
||||
user-select: none; /* Verhindert Textauswahl */
|
||||
-webkit-user-select: none; /* Für Safari */
|
||||
-moz-user-select: none; /* Für Firefox */
|
||||
-ms-user-select: none; /* Für Internet Explorer/Edge */
|
||||
user-select: none; /* Für Safari */
|
||||
user-select: none; /* Für Firefox */
|
||||
user-select: none; /* Für Internet Explorer/Edge */
|
||||
white-space: pre-wrap;
|
||||
overflow: auto;
|
||||
word-wrap: break-word;
|
||||
overflow-wrap: break-word;
|
||||
overflow-wrap: break-word;
|
||||
word-break: normal;
|
||||
padding-top: 2.5em; /* Vergrößerter Abstand am oberen Rand */
|
||||
}
|
||||
|
||||
.text-line {
|
||||
|
|
@ -152,7 +191,7 @@ body {
|
|||
width: 100%;
|
||||
white-space: pre-wrap;
|
||||
font-family: monospace;
|
||||
word-wrap: break-word;
|
||||
overflow-wrap: break-word;
|
||||
overflow-wrap: break-word;
|
||||
word-break: normal;
|
||||
hyphens: none;
|
||||
|
|
@ -172,7 +211,7 @@ body {
|
|||
|
||||
#user-input:focus {
|
||||
border-color: #0d6efd;
|
||||
box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
|
||||
box-shadow: 0 0 0 0.25rem rgb(13 110 253 / 25%);
|
||||
}
|
||||
|
||||
.highlight-correct {
|
||||
|
|
@ -184,6 +223,23 @@ body {
|
|||
color: #dc3545;
|
||||
text-decoration: underline;
|
||||
font-weight: bold;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.incorrect-char-container {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.incorrect-char-overlay {
|
||||
position: absolute;
|
||||
top: -1em;
|
||||
left: 0;
|
||||
font-size: 0.7em;
|
||||
color: #ffc107;
|
||||
background-color: transparent;
|
||||
font-weight: bold;
|
||||
z-index: 10;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.badge {
|
||||
|
|
@ -194,7 +250,7 @@ body {
|
|||
.list-group-item {
|
||||
border: none;
|
||||
padding: 0.75rem 1rem;
|
||||
border-bottom: 1px solid rgba(0,0,0,.125);
|
||||
border-bottom: 1px solid rgb(0 0 0 / 12.5%);
|
||||
}
|
||||
|
||||
.list-group-item:last-child {
|
||||
|
|
@ -219,7 +275,7 @@ body {
|
|||
|
||||
.btn:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
|
||||
box-shadow: 0 4px 8px rgb(0 0 0 / 10%);
|
||||
}
|
||||
|
||||
.btn:active {
|
||||
|
|
@ -255,6 +311,7 @@ body {
|
|||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* Theme-Toggle-Button */
|
||||
#theme-toggle {
|
||||
display: flex;
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||
initializeTheme();
|
||||
document.getElementById('theme-toggle').addEventListener('click', toggleTheme);
|
||||
|
||||
const userInputElement = document.getElementById('user-input');
|
||||
const targetTextElement = document.getElementById('target-text');
|
||||
const nextBtn = document.getElementById('next-btn');
|
||||
const endBtn = document.getElementById('end-btn');
|
||||
|
|
@ -52,6 +51,19 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||
let userInput = ''; // Gesamte Eingabe
|
||||
let keyStrokeCount = 0; // Zähler für alle Tastaturanschläge (inkl. Backspace)
|
||||
let lines = fullText.split('\n');
|
||||
let userScrolled = false; // Flag für manuelles Scrollen
|
||||
|
||||
// Setze Fokus auf das Dokument, um Tastatureingaben zu erfassen
|
||||
document.addEventListener('click', function() {
|
||||
document.body.focus();
|
||||
});
|
||||
document.body.tabIndex = -1;
|
||||
document.body.focus();
|
||||
|
||||
// Event-Listener für manuelles Scrollen
|
||||
targetTextElement.addEventListener('scroll', function() {
|
||||
userScrolled = true;
|
||||
});
|
||||
|
||||
// Berechne die aktuelle Zeile basierend auf currentCharIndex
|
||||
function getCurrentLineIndex() {
|
||||
|
|
@ -88,150 +100,138 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||
return false;
|
||||
});
|
||||
|
||||
// Fokus auf das Eingabefeld setzen
|
||||
userInputElement.focus();
|
||||
|
||||
// Verhindere Copy & Paste für das Eingabefeld
|
||||
userInputElement.addEventListener('paste', function(event) {
|
||||
event.preventDefault();
|
||||
alert('Einfügen (Paste) ist nicht erlaubt! Bitte tippen Sie den Text manuell.');
|
||||
});
|
||||
|
||||
userInputElement.addEventListener('copy', function(event) {
|
||||
event.preventDefault();
|
||||
alert('Kopieren (Copy) ist nicht erlaubt!');
|
||||
});
|
||||
|
||||
userInputElement.addEventListener('cut', function(event) {
|
||||
event.preventDefault();
|
||||
alert('Ausschneiden (Cut) ist nicht erlaubt!');
|
||||
});
|
||||
|
||||
// Verhindere Drag & Drop
|
||||
userInputElement.addEventListener('drop', function(event) {
|
||||
event.preventDefault();
|
||||
alert('Drag & Drop ist nicht erlaubt! Bitte tippen Sie den Text manuell.');
|
||||
});
|
||||
|
||||
// Verhindere das Einfügen über das Kontextmenü (rechte Maustaste)
|
||||
userInputElement.addEventListener('contextmenu', function(event) {
|
||||
event.preventDefault();
|
||||
return false;
|
||||
});
|
||||
|
||||
// Verhindere das Einfügen über Tastenkombinationen (Strg+V, Cmd+V, etc.)
|
||||
userInputElement.addEventListener('keydown', function(event) {
|
||||
// Strg+V oder Cmd+V
|
||||
if ((event.ctrlKey || event.metaKey) && event.key === 'v') {
|
||||
// Tastatureingaben direkt erfassen
|
||||
document.addEventListener('keydown', function(event) {
|
||||
// Verhindere Standardaktionen für Steuertasten, außer Backspace, Enter und Pfeiltasten
|
||||
if (event.ctrlKey || event.metaKey) {
|
||||
event.preventDefault();
|
||||
alert('Einfügen (Strg+V / Cmd+V) ist nicht erlaubt! Bitte tippen Sie den Text manuell.');
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
// Strg+C oder Cmd+C
|
||||
if ((event.ctrlKey || event.metaKey) && event.key === 'c') {
|
||||
// Behandle Pfeiltasten
|
||||
if (event.key === 'ArrowLeft') {
|
||||
event.preventDefault();
|
||||
alert('Kopieren (Strg+C / Cmd+C) ist nicht erlaubt!');
|
||||
return false;
|
||||
}
|
||||
|
||||
// Strg+X oder Cmd+X
|
||||
if ((event.ctrlKey || event.metaKey) && event.key === 'x') {
|
||||
event.preventDefault();
|
||||
alert('Ausschneiden (Strg+X / Cmd+X) ist nicht erlaubt!');
|
||||
return false;
|
||||
}
|
||||
|
||||
// Strg+A oder Cmd+A (Selektion verhindern)
|
||||
if ((event.ctrlKey || event.metaKey) && event.key === 'a') {
|
||||
event.preventDefault();
|
||||
alert('Selektion (Strg+A / Cmd+A) ist nicht erlaubt!');
|
||||
return false;
|
||||
}
|
||||
|
||||
// Rechtsklick-Menü-Tasten (Context Menu key)
|
||||
if (event.key === 'ContextMenu') {
|
||||
event.preventDefault();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
// Starte die Zeitmessung beim ersten Tastendruck und zähle Tastaturanschläge
|
||||
userInputElement.addEventListener('keydown', function(event) {
|
||||
const cursorPosition = userInputElement.selectionStart;
|
||||
const textLength = userInputElement.value.length;
|
||||
let shouldCountKey = false;
|
||||
|
||||
// Zähle Tastaturanschläge für alle Tasten, die keine Steuertasten sind (inkl. Backspace)
|
||||
// Beachte: event.key für Backspace ist 'Backspace'
|
||||
if (event.key.length === 1 || event.key === 'Backspace') {
|
||||
shouldCountKey = true;
|
||||
}
|
||||
// Pfeiltasten: Nur zählen, wenn sich der Cursor tatsächlich bewegt
|
||||
else if (event.key === 'ArrowLeft') {
|
||||
if (cursorPosition > 0) {
|
||||
shouldCountKey = true;
|
||||
}
|
||||
} else if (event.key === 'ArrowRight') {
|
||||
if (cursorPosition < textLength) {
|
||||
shouldCountKey = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldCountKey) {
|
||||
keyStrokeCount++;
|
||||
if (!startTime) {
|
||||
startTime = new Date();
|
||||
}
|
||||
keyStrokeCount++;
|
||||
// Aktualisiere die Statistik sofort, um die Änderung anzuzeigen
|
||||
if (currentCharIndex > 0) {
|
||||
currentCharIndex--;
|
||||
updateTextDisplay();
|
||||
}
|
||||
updateStatistics();
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.key === 'ArrowRight') {
|
||||
event.preventDefault();
|
||||
keyStrokeCount++;
|
||||
if (!startTime) {
|
||||
startTime = new Date();
|
||||
}
|
||||
if (currentCharIndex < userInput.length) {
|
||||
currentCharIndex++;
|
||||
updateTextDisplay();
|
||||
}
|
||||
updateStatistics();
|
||||
return;
|
||||
}
|
||||
|
||||
// Behandle Backspace
|
||||
if (event.key === 'Backspace') {
|
||||
event.preventDefault();
|
||||
keyStrokeCount++;
|
||||
if (!startTime) {
|
||||
startTime = new Date();
|
||||
}
|
||||
if (userInput.length > 0 && currentCharIndex > 0) {
|
||||
userInput = userInput.slice(0, currentCharIndex - 1) + userInput.slice(currentCharIndex);
|
||||
currentCharIndex--;
|
||||
updateTextDisplay();
|
||||
updateStatistics();
|
||||
} else {
|
||||
updateStatistics();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Behandle Enter (falls im Text vorhanden)
|
||||
if (event.key === 'Enter') {
|
||||
event.preventDefault();
|
||||
if (currentCharIndex < fullText.length && fullText[currentCharIndex] === '\n') {
|
||||
userInput = userInput.slice(0, currentCharIndex) + '\n' + userInput.slice(currentCharIndex);
|
||||
currentCharIndex++;
|
||||
keyStrokeCount++;
|
||||
if (!startTime) {
|
||||
startTime = new Date();
|
||||
}
|
||||
updateTextDisplay();
|
||||
updateStatistics();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Ignoriere andere Steuertasten
|
||||
if (event.key.length > 1 && event.key !== ' ') {
|
||||
return;
|
||||
}
|
||||
|
||||
// Behandle normale Zeichen
|
||||
event.preventDefault();
|
||||
if (currentCharIndex < fullText.length) {
|
||||
// Wenn der Cursor innerhalb des bereits eingegebenen Textes steht, ersetze das Zeichen
|
||||
// Andernfalls hänge das Zeichen an
|
||||
if (currentCharIndex < userInput.length) {
|
||||
// Ersetze das Zeichen an der aktuellen Position
|
||||
userInput = userInput.slice(0, currentCharIndex) + event.key + userInput.slice(currentCharIndex + 1);
|
||||
} else {
|
||||
// Hänge das Zeichen am Ende an
|
||||
userInput = userInput.slice(0, currentCharIndex) + event.key + userInput.slice(currentCharIndex);
|
||||
}
|
||||
currentCharIndex++;
|
||||
keyStrokeCount++;
|
||||
if (!startTime) {
|
||||
startTime = new Date();
|
||||
}
|
||||
updateTextDisplay();
|
||||
updateStatistics();
|
||||
|
||||
// Wenn die gesamte Lektion abgeschlossen ist
|
||||
if (currentCharIndex === fullText.length) {
|
||||
// Speichere die Statistiken für diese Lektion
|
||||
const lessonIndex = window.currentLessonIndex;
|
||||
const charsPerMinute = parseInt(speedElement.textContent);
|
||||
const errorRate = parseFloat(errorRateElement.textContent);
|
||||
const wpm = parseInt(wpmElement.textContent);
|
||||
|
||||
fetch('/save_lesson_statistics', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
lesson_index: lessonIndex,
|
||||
chars_per_minute: charsPerMinute,
|
||||
error_rate: errorRate,
|
||||
wpm: wpm
|
||||
})
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.status === 'success') {
|
||||
alert('Lektion beendet! Statistiken wurden gespeichert.');
|
||||
} else {
|
||||
alert('Lektion beendet, aber Statistiken konnten nicht gespeichert werden.');
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Fehler beim Speichern der Statistiken:', error);
|
||||
alert('Lektion beendet! (Fehler beim Speichern der Statistiken)');
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Aktualisiere die Statistik bei jedem Tastendruck (keyup)
|
||||
userInputElement.addEventListener('keyup', function() {
|
||||
userInput = this.value;
|
||||
currentCharIndex = userInput.length;
|
||||
|
||||
// Aktualisiere die Anzeige bei jeder Änderung
|
||||
updateTextDisplay();
|
||||
|
||||
// Wenn die gesamte Lektion abgeschlossen ist
|
||||
if (currentCharIndex === fullText.length) {
|
||||
// Speichere die Statistiken für diese Lektion
|
||||
const lessonIndex = window.currentLessonIndex;
|
||||
const charsPerMinute = parseInt(speedElement.textContent);
|
||||
const errorRate = parseFloat(errorRateElement.textContent);
|
||||
const wpm = parseInt(wpmElement.textContent);
|
||||
|
||||
fetch('/save_lesson_statistics', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
lesson_index: lessonIndex,
|
||||
chars_per_minute: charsPerMinute,
|
||||
error_rate: errorRate,
|
||||
wpm: wpm
|
||||
})
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.status === 'success') {
|
||||
alert('Lektion beendet! Statistiken wurden gespeichert.');
|
||||
} else {
|
||||
alert('Lektion beendet, aber Statistiken konnten nicht gespeichert werden.');
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Fehler beim Speichern der Statistiken:', error);
|
||||
alert('Lektion beendet! (Fehler beim Speichern der Statistiken)');
|
||||
});
|
||||
}
|
||||
|
||||
updateStatistics();
|
||||
});
|
||||
|
||||
// Funktion zum Aktualisieren der Lektionsmarkierung
|
||||
function updateLessonHighlight(lessonIndex) {
|
||||
|
|
@ -278,10 +278,9 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||
startTime = null;
|
||||
keyStrokeCount = 0; // Zurücksetzen des Tastaturanschlagszählers
|
||||
lines = fullText.split('\n');
|
||||
userScrolled = false; // Reset Scroll-Flag
|
||||
updateTextDisplay();
|
||||
document.getElementById('lesson-title').textContent = data.title;
|
||||
userInputElement.value = '';
|
||||
userInputElement.focus();
|
||||
updateStatistics();
|
||||
// Aktualisiere die Markierung der aktuellen Lektion
|
||||
updateLessonHighlight(lessonIndex);
|
||||
|
|
@ -314,11 +313,10 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||
startTime = null;
|
||||
keyStrokeCount = 0; // Zurücksetzen des Tastaturanschlagszählers
|
||||
lines = fullText.split('\n');
|
||||
userScrolled = false; // Reset Scroll-Flag
|
||||
updateTextDisplay();
|
||||
// Aktualisiere den Lektionstitel
|
||||
document.getElementById('lesson-title').textContent = data.title;
|
||||
userInputElement.value = '';
|
||||
userInputElement.focus(); // Fokus zurück auf Eingabefeld
|
||||
updateStatistics();
|
||||
// Aktualisiere die Markierung der aktuellen Lektion
|
||||
updateLessonHighlight(data.index);
|
||||
|
|
@ -383,15 +381,23 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||
}
|
||||
|
||||
// Hilfsfunktion zum Hervorheben eines Zeichens
|
||||
function highlightChar(char, type) {
|
||||
function highlightChar(char, type, isCursor = false, incorrectChar = null) {
|
||||
let className = `highlight-${type}`;
|
||||
if (isCursor) {
|
||||
className += ' cursor-char';
|
||||
}
|
||||
if (char === ' ') {
|
||||
return `<span class="highlight-${type} highlight-space">·</span>`;
|
||||
return `<span class="${className} highlight-space">·</span>`;
|
||||
} else if (char === '\t') {
|
||||
return `<span class="highlight-${type} highlight-tab">→</span>`;
|
||||
return `<span class="${className} highlight-tab">→</span>`;
|
||||
} else if (char === '\n') {
|
||||
return '<span class="highlight-newline">↵</span><br>';
|
||||
return `<span class="${className} highlight-newline">↵</span><br>`;
|
||||
} else {
|
||||
return `<span class="highlight-${type}">${char}</span>`;
|
||||
if (type === 'incorrect' && incorrectChar !== null) {
|
||||
return `<span class="${className} incorrect-char-container">${char}<span class="incorrect-char-overlay">${incorrectChar}</span></span>`;
|
||||
} else {
|
||||
return `<span class="${className}">${char}</span>`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -421,14 +427,15 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||
for (let i = 0; i < line.length; i++) {
|
||||
const currentChar = line[i];
|
||||
const absoluteIndex = lineStart + i;
|
||||
const isCursor = (absoluteIndex === currentCharIndex);
|
||||
if (absoluteIndex < userInput.length) {
|
||||
if (userInput[absoluteIndex] === currentChar) {
|
||||
highlightedLine += highlightChar(currentChar, 'correct');
|
||||
highlightedLine += highlightChar(currentChar, 'correct', isCursor);
|
||||
} else {
|
||||
highlightedLine += highlightChar(currentChar, 'incorrect');
|
||||
highlightedLine += highlightChar(currentChar, 'incorrect', isCursor, userInput[absoluteIndex]);
|
||||
}
|
||||
} else {
|
||||
highlightedLine += highlightChar(currentChar, 'neutral');
|
||||
highlightedLine += highlightChar(currentChar, 'neutral', isCursor);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -436,14 +443,15 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||
if (j < lines.length - 1) {
|
||||
const newlinePos = lineStart + line.length;
|
||||
const newlineChar = '\n';
|
||||
const isCursor = (newlinePos === currentCharIndex);
|
||||
if (newlinePos < userInput.length) {
|
||||
if (userInput[newlinePos] === newlineChar) {
|
||||
highlightedLine += highlightChar(newlineChar, 'correct');
|
||||
highlightedLine += highlightChar(newlineChar, 'correct', isCursor);
|
||||
} else {
|
||||
highlightedLine += highlightChar(newlineChar, 'incorrect');
|
||||
highlightedLine += highlightChar(newlineChar, 'incorrect', isCursor, userInput[newlinePos]);
|
||||
}
|
||||
} else {
|
||||
highlightedLine += highlightChar(newlineChar, 'neutral');
|
||||
highlightedLine += highlightChar(newlineChar, 'neutral', isCursor);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -453,10 +461,9 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||
|
||||
targetTextElement.innerHTML = newHTML;
|
||||
|
||||
// Scrolle zur aktuellen Zeile (oben)
|
||||
const currentLineElement = targetTextElement.querySelector('.current-line');
|
||||
if (currentLineElement) {
|
||||
currentLineElement.scrollIntoView({ block: 'start', behavior: 'smooth' });
|
||||
// Behalte Scroll-Position bei, es sei denn der Benutzer hat nicht manuell gescrollt
|
||||
if (!userScrolled) {
|
||||
targetTextElement.scrollTop = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -527,6 +534,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// Initialisiere Statistik und Textfarben
|
||||
updateTextDisplay();
|
||||
updateStatistics();
|
||||
|
|
|
|||
|
|
@ -49,17 +49,6 @@
|
|||
window.currentCharIndex = 0;
|
||||
</script>
|
||||
|
||||
<!-- Eingabefeld -->
|
||||
<div class="mb-4">
|
||||
<h5 class="card-title">Ihre Eingabe:</h5>
|
||||
<textarea
|
||||
id="user-input"
|
||||
class="form-control"
|
||||
rows="3"
|
||||
placeholder="Tippen Sie hier..."
|
||||
autofocus
|
||||
></textarea>
|
||||
</div>
|
||||
|
||||
<!-- Fortschritt und Statistik mit Toggle-Funktion -->
|
||||
<div class="row mb-4">
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue