Class 组合未应用新样式

Class combination not applying new style

我有一个定义如下的 svelte 按钮:

    <span class="nav-button" on:click={e => setActive(e.target,"nav-button")}>
        ...
    </span>

当下面的 setActive() 函数是 运行 时应用 .active class:

    // Toggles the active status of an element
    function setActive(e, bubble?:string) {

        // Optionally bubbles to spesified parent element
        if(bubble) while(!e.classList.contains(bubble)) e = e.parentElement;

        (e.classList.contains("active"))? e.classList.remove("active"):e.classList.add("active");
    }

添加.active class,但不添加样式

.nav-button 在 SCSS 中定义为:

    .nav-button {   
        box-shadow: -7px -7px 20px 0px var(--shadow-primary),
        -4px -4px 5px 0px var(--shadow-primary),
        7px 7px 20px 0px #0002,
        4px 4px 5px 0px #0001,
        inset 0px 0px 0px 0px var(--shadow-primary),
        inset 0px 0px 0px 0px #0001,
        inset 0px 0px 0px 0px var(--shadow-primary),
        inset 0px 0px 0px 0px #0001;

        transition:box-shadow 0.25s cubic-bezier(.79,.21,.06,.81);


        &.active {
            box-shadow: 0px 0px 0px 0px var(--shadow-primary),
            0px 0px 0px 0px var(--shadow-primary),
            0px 0px 0px 0px #0001,
            0px 0px 0px 0px #0001,
            inset -7px -7px 20px 0px var(--shadow-primary),
            inset -4px -4px 5px 0px var(--shadow-primary),
            inset 7px 7px 20px 0px #0003,
            inset 4px 4px 5px 0px #0001 !important;
        }
    }

有关视频示例,请参阅 here

如果有人能帮助我,将不胜感激!

非常感谢@dagalti

.nav-buttonclass必须改成:

    :global(.nav-button) { 
        box-shadow: -7px -7px 20px 0px var(--shadow-primary),
            -4px -4px 5px 0px var(--shadow-primary),
            7px 7px 20px 0px #0002,
            4px 4px 5px 0px #0001,
            inset 0px 0px 0px 0px var(--shadow-primary),
            inset 0px 0px 0px 0px #0001,
            inset 0px 0px 0px 0px var(--shadow-primary),
            inset 0px 0px 0px 0px #0001;

            transition:box-shadow 0.25s cubic-bezier(.79,.21,.06,.81);


            &.active {
                box-shadow: 0px 0px 0px 0px var(--shadow-primary),
                0px 0px 0px 0px var(--shadow-primary),
                0px 0px 0px 0px #0001,
                0px 0px 0px 0px #0001,
                inset -7px -7px 20px 0px var(--shadow-primary),
                inset -4px -4px 5px 0px var(--shadow-primary),
                inset 7px 7px 20px 0px #0003,
                inset 4px 4px 5px 0px #0001 !important;
            }
        }

你可以看到工作示例here

你需要 :global 的原因是因为编译器发现 .active class 没有在标记中的任何地方使用,它将删除它,添加 :global修饰符告诉编译器:这个class应用在你看不到的地方,请保留它。

请注意,使用 :global 方法也会从您的样式中删除范围,这意味着如果这个 class 出现在您项目的其他地方,它也会应用到那里,这是这样做的主要原因真的是不得已了

但对于你的情况你不需要,你只需要完全拥抱 Svelte。

首先要记住的是,在使用 Svelte 时,在 JavaScript 中进行 DOM 操作通常是一种不好的做法,相反,您应该依赖组件的状态来而是自己更新。

就是说,您可以废弃 setActive 函数并将其替换为单个变量:

  let active

目标是简单地在 active 中放置当前元素的某种标识。我们可以简单地通过更改 on:click

来做到这一点
<span on:click={() => active = 1}>...</span>
<span on:click={() => active = 2}>...</span>

(随意更改数字,例如字符串或 ID)

最终使用 Svelte

中的 条件 classes 功能
<span class:active={active === 1}>...</span>

使用符号:class:xxx={condition}> 将 class xxx 添加到您的元素,如果 condition 计算是的。

所以总代码为:

<script>
  let active
</script>

<span class:active={active === 1} class="nav_button" on:click={() => active = 1}>...</span>
<span class:active={active === 2} class="nav_button" on:click={() => active = 2}>...</span>
<span class:active={active === 3} class="nav_button" on:click={() => active = 3}>...</span>

<style>
 /* here your styles */
</style>

这样 class active 实际用于标记中,编译器不会为您删除它,从而降低在其他地方应用与 class 相同规则的风险仍将作用于此组件。

(我个人也认为这样可以让代码更容易理解)