export class Steam {
    constructor() {
        this.init();
    }

    init() {
        this.cleanup();
        this.bindEvents();
        this.animateProgressBars();
    }
    
    cleanup() {
        const container = document.querySelector('.steam-container');
        if (container) {
        }
    }

    bindEvents() {
        const container = document.querySelector('.steam-container');
        if (!container) {
            return;
        }
        this.clickHandler = (e) => {
            const header = e.target.closest('.steam-group__header');
            if (header) {
                e.preventDefault();
                e.stopPropagation();
                this.toggleGroup(header);
            }
        };

        container.addEventListener('click', this.clickHandler);
    }

    toggleGroup(header) {
        const group = header.closest('.steam-group');
        if (group) {
            group.classList.toggle('steam-is-collapsed');
            
            const isCollapsed = group.classList.contains('steam-is-collapsed');            
            const id = group.dataset.groupId;
            if (id) {
                localStorage.setItem(`steam-group-${id}`, isCollapsed.toString());
            }
        } else {
            console.warn("Group container not found for header", header);
        }
    }

    animateProgressBars() {
        const bars = document.querySelectorAll('.steam-summary__progress-bar');
        bars.forEach(bar => {
            const width = bar.dataset.width;
            if (width) {
                // Small delay to ensure transition plays
                setTimeout(() => {
                    bar.style.width = width;
                }, 100);
            }
        });
    }
}
⚠⚠    以下内容为AI分析的结果,请根据实际情况进行判断。

这段代码定义了一个名为 Steam 的 ES6 类,用来控制页面上某些“分组折叠/展开”和进度条动画的交互行为。下面按部分解释它的作用、运行流程以及一些注意点和改进建议。

主要职责

  • 监听容器内的点击事件,实现“分组折叠/展开”(通过添加/移除 CSS 类实现)。
  • 把分组的折叠状态保存到 localStorage(以便持久化)。
  • 给带有 data-width 的进度条元素设置宽度,从而触发 CSS 的宽度过渡动画。

构造与初始化

  • constructor():实例化时调用 this.init()。
  • init():顺序执行 cleanup()、bindEvents()、animateProgressBars()。也就是说每次初始化会先清理(目前为空实现),再绑定事件,然后启动进度条的动画。

DOM 选择器与事件代理

  • 主要目标容器为 document.querySelector('.steam-container')。
  • bindEvents() 在该容器上绑定了一个 click 事件处理器(事件代理)。
    • clickHandler 使用 e.target.closest('.steam-group__header') 找到最近的分组 header(支持在 header 内点击任意子节点也能触发)。
    • 如果点到了 header,就阻止默认行为与事件冒泡,并调用 this.toggleGroup(header)。

折叠/展开逻辑:toggleGroup(header)

  • 找到 header 所属的最近 .steam-group 容器。
  • 切换该容器上的 class .steam-is-collapsed(用于控制样式折叠/展开)。
  • 从 group 的 data-group-id(dataset.groupId)读取 id,如果存在则把当前折叠状态(true/false)保存到 localStorage,键名为 steam-group-{id},值为字符串 "true" 或 "false"。
  • 如果没找到 group,则在控制台警告。

进度条动画:animateProgressBars()

  • 查找所有 .steam-summary__progress-bar。
  • 对每个元素读取 data-width(bar.dataset.width),如果存在,则在 100ms 后把元素的 style.width 设为该值,从而触发 CSS 的 transition(假定 CSS 对 width 有过渡效果)。
  • 这里用短延迟是为了确保元素初始样式已应用,能看到过渡动画。

cleanup()

  • 当前实现只是查找 container,但没有做任何清理。预期用途通常是移除已绑定的事件监听器或恢复 DOM 到初始状态。

如何使用

  • 在页面相应 DOM 就绪后,创建实例:new Steam(); 实例化时会自动执行 init。

注意事项与改进建议

  • cleanup() 为空:如果多次调用 init()(或多次 new Steam),会重复绑定 click 监听器,可能导致重复触发。建议在 cleanup 中移除事件监听器,例如:
    • 在 bindEvents 中把 this.clickHandler 存为实例属性(代码已存)。cleanup 应移除:container.removeEventListener('click', this.clickHandler)。
  • localStorage 恢复状态缺失:类把折叠状态写入了 localStorage,但没有在 init 时读取并应用它。可以在 init 或一个专门的方法里遍历 .steam-group 元素,读取对应的 localStorage 键并应用 .steam-is-collapsed。
  • 防止默认/停止冒泡:当前对 header 的点击执行了 e.preventDefault() 和 e.stopPropagation(),这可能会影响 header 内本应有的链接或其它事件。根据需求考虑是否需要这两个调用。
  • 兼容性:代码使用 closest 和 dataset,较旧浏览器可能不支持,需要 polyfill。
  • 进度条动画依赖 CSS:确保 .steam-summary__progress-bar 在初始时 width 为 0 或其他初始值,并有 transition: width 以便看到动画效果;否则只是直接设置宽度。
  • 键名冲突:localStorage 键使用 steam-group-{id},确保 id 唯一且没有安全/隐私问题。
  • 无障碍和可访问性:折叠控制最好配合 ARIA 属性(aria-expanded)以便屏幕阅读器识别状态变化。

总结 这个类通过事件代理控制分组折叠并把状态持久化到 localStorage,同时通过设置元素宽度触发进度条动画。但当前 cleanup 未实现与状态还原未实现,会引起重复绑定或无法恢复之前的折叠状态。可以按上面建议进行补充和改进。需要我把这些改进写成代码示例吗?

评论加载中...