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

如何为Storybook Angular添加窗口大小调整事件监听器

解决Storybook Angular中窗口/视口调整时触发函数的问题

常规的@HostListener('window:resize')在Storybook环境中失效,主要源于Storybook的iframe隔离机制,以下是几个可行的解决方法:

方法1:使用RxJS监听resize事件(推荐)

通过RxJS的fromEvent创建resize事件流,配合防抖避免频繁触发,同时在组件销毁时取消订阅防止内存泄漏:

import { Component, OnInit, OnDestroy } from '@angular/core';
import { fromEvent } from 'rxjs';
import { debounceTime } from 'rxjs/operators';

@Component({
  selector: 'app-your-tabs-component',
  templateUrl: './your-tabs-component.component.html'
})
export class YourTabsComponent implements OnInit, OnDestroy {
  private resizeSubscription: any;

  ngOnInit(): void {
    // 监听窗口resize事件,防抖300ms减少触发频率
    this.resizeSubscription = fromEvent(window, 'resize')
      .pipe(debounceTime(300))
      .subscribe(() => {
        this.updateVisibleTabs(); // 调用你的标签数量计算函数
      });
  }

  ngOnDestroy(): void {
    // 组件销毁时取消订阅,避免内存泄漏
    this.resizeSubscription?.unsubscribe();
  }

  updateVisibleTabs(): void {
    // 你的计算屏幕尺寸、更新可见标签数量的逻辑
    const screenWidth = window.innerWidth;
    // ... 其他业务逻辑
  }
}

方法2:通过DOCUMENT服务监听resize

注入Angular的DOCUMENT服务,获取当前窗口对象并绑定resize事件:

import { Component, OnInit, OnDestroy, Inject } from '@angular/core';
import { DOCUMENT } from '@angular/common';

@Component({
  selector: 'app-your-tabs-component',
  templateUrl: './your-tabs-component.component.html'
})
export class YourTabsComponent implements OnInit, OnDestroy {
  private resizeHandler: () => void;

  constructor(@Inject(DOCUMENT) private document: Document) {}

  ngOnInit(): void {
    this.resizeHandler = () => this.updateVisibleTabs();
    // 绑定到当前窗口的resize事件
    this.document.defaultView?.addEventListener('resize', this.resizeHandler);
  }

  ngOnDestroy(): void {
    // 移除事件监听
    this.document.defaultView?.removeEventListener('resize', this.resizeHandler);
  }

  updateVisibleTabs(): void {
    // 你的业务逻辑
  }
}

方法3:适配Storybook视口切换事件

如果需要精准响应Storybook的视口切换操作(而非单纯窗口resize),可以在故事文件中利用Storybook的addons API监听视口变化:

import { Meta, Story } from '@storybook/angular';
import { YourTabsComponent } from './your-tabs-component.component';

export default {
  title: 'YourTabsComponent',
  component: YourTabsComponent,
} as Meta;

const Template: Story<YourTabsComponent> = (args: YourTabsComponent) => ({
  component: YourTabsComponent,
  props: args,
});

export const Default = Template.bind({});
Default.decorators = [
  (story) => {
    // 监听Storybook视口切换事件
    const viewportAddon = window['__STORYBOOK_ADDONS'].get('storybook/viewport');
    viewportAddon.on('viewport:change', () => {
      // 获取组件实例并调用更新函数
      const component = document.querySelector('app-your-tabs-component')?.componentInstance;
      component?.updateVisibleTabs();
    });
    return story();
  },
];

内容的提问来源于stack exchange,提问作者Anurag Singh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 18:43:22