You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Svelte中用JavaScript实现点击树结构仅单个div激活聚焦的方案

核心问题排查

你的代码无法实现单选效果的核心原因有2个:

  • for循环语法完全错误:for 语句的三个参数顺序应为「初始化语句、循环条件、迭代语句」,你写反了循环条件和迭代语句的位置,导致重置旧元素聚焦状态的逻辑一次都没有执行过
  • 每次点击都往history数组新增当前元素的引用,会导致数组无限膨胀,冗余数据越来越多,遍历效率持续降低

最优修改方案

不需要用历史记录机制实现单选逻辑,只需要维护一个全局的「当前激活元素」引用即可,修改后的代码如下:

<script lang="ts">
    import type { FrontendFile } from '$lib/front';
    export let content: FrontendFile;
    // 替换原有history数组,所有递归节点共用同一个激活状态引用
    export let activeFile: FrontendFile | null = null;
    let text = '';

    function focusUnfocus() {
        // 点击已激活元素则取消激活
        if (activeFile === content) {
            activeFile = null;
            content.status.focused = false;
        } else {
            // 先重置上一个激活元素的状态
            if (activeFile) {
                activeFile.status.focused = false;
            }
            // 激活当前元素
            content.status.focused = true;
            activeFile = content;
        }
        // 同步样式类
        text = content.status.focused ? 'font-black' : '';
    }
</script>

<div class="{text}" on:click={focusUnfocus}>
    {content.name}
</div>
{#each content.children as sub}
    <!-- 递归传递激活状态的绑定 -->
    <svelte:self bind:activeFile content={sub} />
{/each}

调用该组件时,在父层初始化activeFile即可:

<!-- 父组件调用示例 -->
<Tree content={rootFile} bind:activeFile={null} />

临时兼容方案

如果你一定要保留原有的history逻辑,只需要修正for循环的语法即可生效,但不推荐长期使用该方案:

// 修正后可以正常遍历的for循环
for (let i=0; i < history.length; i++) {
    history[i].status.focused = false;
}

内容的提问来源于stack exchange,提问作者Willem Vanhulle

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 05:24:05