Svelte中用:global()和data属性为动态类设样式报错
解决方案
一、改用动态类绑定(推荐,符合Svelte最佳实践)
Svelte会保留与动态绑定关联的类,不会自动移除,因此直接用class:correct和class:incorrect绑定状态即可,无需使用data-*属性和:global()。
1. 维护字母状态
在<script>中添加状态数组,记录每个字母的正确/错误状态:
// 初始化所有字母状态为null(未输入) let letterStates: ('correct' | 'incorrect' | null)[][] = words.map(word => Array(word.length).fill(null));
2. 修改字母渲染逻辑
更新模板中的字母循环,绑定动态类:
<div class="words"> {#each words as word, wordIdx} <span class="word"> {#each word as letter, letterIdx} <span class="letter" class:correct={letterStates[wordIdx][letterIdx] === 'correct'} class:incorrect={letterStates[wordIdx][letterIdx] === 'incorrect'} > {letter} </span> {/each} </span> {/each} </div>
3. 更新校验逻辑
修改checkLetter函数,更新状态数组而非操作dataset:
function checkLetter() { if (letterIndex >= words[wordIndex].length) return; // 避免越界 const currentLetter = words[wordIndex][letterIndex]; if (typedLetter === currentLetter) { letterStates[wordIndex][letterIndex] = 'correct'; increaseScore(); } else { letterStates[wordIndex][letterIndex] = 'incorrect'; } }
4. 简化CSS
直接编写类选择器,无需:global():
.words { // ...原有样式 .letter { opacity: 0.4; transition: all 0.3s ease; &.correct { opacity: 0.8; } &.incorrect { color: var(--primary); opacity: 1; } } }
二、修复:global()使用方式(若坚持用data属性)
原错误是因为Svelte不允许在嵌套选择器的&后直接拼接:global(...),需调整选择器结构:
修改CSS写法
将包含data-letter的选择器整体声明为全局,放在.words嵌套外或调整嵌套方式:
.words { // ...原有样式 .letter { opacity: 0.4; transition: all 0.3s ease; } } :global(.words .letter[data-letter='correct']) { opacity: 0.8; } :global(.words .letter[data-letter='incorrect']) { color: var(--primary); opacity: 1; }
或者在SCSS嵌套内使用全局选择器包裹完整规则:
.words { // ...原有样式 :global(.letter[data-letter='correct']) { opacity: 0.8; } :global(.letter[data-letter='incorrect']) { color: var(--primary); opacity: 1; } }
额外优化点
- 处理单词切换:当
letterIndex超过当前单词长度时,自动切换到下一个单词并重置letterIndex,避免letterEl获取失败 - 限制输入为单个字符:当前
input绑定typedLetter会允许输入多个字符,可在updateGameState中只取最后一个字符,或每次输入后清空input值 - 避免空输入触发校验:在
updateGameState开头判断typedLetter是否为空,为空则直接返回
内容的提问来源于stack exchange,提问作者james-clarke
相关产品推荐
相关产品推荐

