乐趣区

关于sap:SAP-电商云-Spartacus-UI-的响应式-UI-实现细节

在文件 projects\storefrontlib\layout\config\default-layout.config.ts 里,定义了各个屏幕尺寸所对应的 breakpoint:

export const defaultLayoutConfig: LayoutConfig = {
  breakpoints: {
    xs: 576,
    sm: 768,
    md: 992,
    lg: 1200,
    xl: {min: 1200,},
  },
};

留神这个 breakpoint 和编程语言里的断点没有关系。

breakpoint.service.ts 的 getBreakpoint 办法,提供了依据以后屏幕宽度返回最合适的 breakpoint:

以这个 id 为 trigger 的按钮为例,它是齐全 css 驱动的:

这个按钮的 css:

btn btn-action btn-block dialog-trigger

该按钮在 lg 这个 breakpoint 状况下,会被设置为 display:none:

而 Spartacus 利用代码怎么晓得以后的屏幕尺寸对应的 break point 呢?

答案是咱们本人实现的 breakpoint.service.ts.

首先定义枚举类型 BREAKPOINT:

export enum BREAKPOINT {
  xs = 'xs',
  sm = 'sm',
  md = 'md',
  lg = 'lg',
  xl = 'xl',
}

而后依据以后代码的运行环境进行计算:

breakpoint$: Observable<BREAKPOINT> = isPlatformBrowser(this.platform)
    ? this.winRef.resize$.pipe(map((event) => this.getBreakpoint((<Window>event.target).innerWidth)),
        distinctUntilChanged())
    : of(this.fallbackBreakpoint);

  constructor(
    protected winRef: WindowRef,
    protected layoutConfig: LayoutConfig,
    @Inject(PLATFORM_ID) protected platform: any
  ) {}

如果以后运行在浏览器环境下,isPlatformBrowser(this.platform) 返回 true,那么进入三元表达式后面的分支,调用 this.getBreakpoint 依据以后屏幕的 innerWidth,获取对应的 breakpoint.

同时,一旦有 resize 事件产生,会主动从新计算新的 breakpoint. 每次 resize 事件产生时,产生的 event 对象 event.target 指向 Window 对象,该对象的 innerWidth 即是新的屏幕宽度。

如何捕获屏幕的 resize 事件?

 get resize$(): Observable<any> {if (!this.nativeWindow) {return of(null);
    } else {return fromEvent(this.nativeWindow, 'resize').pipe(debounceTime(300),
        startWith({target: this.nativeWindow}),
        distinctUntilChanged());
    }
  }

这里咱们应用了 rxJs 的 fromEvent 和 debounce, 将 window 对象产生的 resize 事件,做了一个 300 毫秒的限流,意思是当 resize 事件触发后,如果 300 毫秒之内并没有新的 resize 事件产生时,再把这个 resize 事件,交给 Observable 执行链的上游解决,即从新获取 breakpoint.

如果以后代码在服务器端 Node.js 环境中运行,进入三元表达式问号前面的分支:of(this.fallbackBreakpoint);

返回最小屏幕尺寸对应的 breakpoint,这也体现了 mobile first 的设计思路。

更多 Jerry 的原创文章,尽在:” 汪子熙 ”:

退出移动版