Stories

Detail Return Return

SAP 電商雲 Spartacus UI 的響應式 UI 實現細節 - Stories Detail

在文件 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的原創文章,盡在:"汪子熙":

user avatar xingchendahai_68d7dff410962 Avatar boxuegu Avatar shenchendexiaoyanyao Avatar daimajiangxin Avatar shine_zhu Avatar webweb Avatar user_cwhpnk0j Avatar yixiaoxuan_5aa7726674d5c Avatar chongdongdedaxiongmao_kxfei Avatar
Favorites 9 users favorite the story!
Favorites

Add a new Comments

Some HTML is okay.