我目前正在开发一款类似monkeytype.com的打字游戏.每个单独的字母都与类相关联,这些类根据用户输入的字母是否与预期的字母匹配,动态地从空字符串更改为"正确"或"不正确".
因为Svelte会自动删除未使用的类,所以"正确"和"不正确"类可能不会立即存在于DOM中.因此,当这些字母类被激活时,我很难找到一种有效的方法来将不同的样式应用到它们.
以下是我的代码:
<script lang="ts">
type Game = 'waiting for game' | 'in progress' | 'game over';
type Word = string;
let game: Game = 'waiting for game';
let typedLetter = '';
let words: Word[] = 'the quick brown fox jumped over the lazy dog'.split(' ');
let wordIndex = 0;
let letterIndex = 0;
let correctLetter = 0;
let correctLetters = 0;
let wordsEl: HTMLDivElement;
let letterEl: HTMLSpanElement;
let inputEl: HTMLInputElement;
function startGame() {
setGameState('in progress');
}
function setGameState(state: Game) {
game = state;
}
function updateGameState() {
setLetter();
checkLetter();
nextLetter();
resetLetter();
}
function setLetter() {
const isWordCompleted = letterIndex > words[wordIndex].length - 1;
if (!isWordCompleted) {
letterEl = wordsEl.children[wordIndex].children[letterIndex] as HTMLSpanElement;
}
}
function checkLetter() {
const currentLetter = words[wordIndex][letterIndex];
if (typedLetter === currentLetter) {
letterEl.dataset.letter = 'correct';
increaseScore();
}
if (typedLetter !== currentLetter) {
letterEl.dataset.letter = 'incorrect';
}
}
function increaseScore() {
correctLetters += 1;
}
function nextLetter() {
letterIndex += 1;
}
function resetLetter() {
typedLetter = '';
}
function handleKeydown(event: KeyboardEvent) {
if (event.code === 'Space') {
event.preventDefault();
}
if (game === 'waiting for game') {
startGame();
}
}
</script>
<div class="game" data-game={game}>
<input
type="text"
class="input"
bind:this={inputEl}
bind:value={typedLetter}
on:input={updateGameState}
on:keydown={handleKeydown}
/>
</div>
<div class="words" bind:this={wordsEl}>
{#each words as word}
<span class="word">
{#each word as letter}
<span class="letter">{letter}</span>
{/each}
</span>
{/each}
</div>
<style lang="scss">
.words {
--line-height: 1em;
--lines: 3;
width: 100%;
max-height: calc(var(--line-height) * var(--lines) * 1.42);
display: flex;
flex-wrap: wrap;
gap: 0.6em;
position: relative;
font-size: 1.5rem;
line-height: var(--line-height);
overflow: hidden;
user-select: none;
.letter {
opacity: 0.4;
transition: all 0.3s ease;
&:global([data-letter='correct']) {
opacity: 0.8;
}
&:global([data-letter='incorrect']) {
color: var(--primary);
opacity: 1;
}
}
}
</style>
我曾try 对数据属性使用:selectorssvelte(css-invalid-global-selector-position)‘.,但这导致了以下错误消息:’:Global(...)不在 Select 器序列的开头不应包含类型或通用GLOBALSvelte和所有其他套餐都是最新的.