文章目录
一、Overlay简介
Overlay 包提供了一种在屏幕上打开浮动面板的方法。比如popover、dialog等组件的实现就用到了Overlay包。
二、Overlay 源码阅读
2.1 OverlayConfig 浮层配置
创建overlay时使用的初始化配置。
// 创建overlay时使用的初始化配置
export class OverlayConfig {
// 位置策略
positionStrategy?: PositionStrategy;
// 滚动策略
scrollStrategy?: ScrollStrategy = new NoopScrollStrategy();
// 给 overlay pane 添加自定义样式
panelClass?: string | string[] = '';
// overlay是否需要背景幕布
hasBackdrop?: boolean = false;
// 自定义背景幕布的样式
backdropClass?: string | string[] = 'cdk-overlay-dark-backdrop';
// overlay panel 的宽、高、最大最小宽高,值为number时单位是px
width?: number | string;
height?: number | string;
minWidth?: number | string;
minHeight?: number | string;
maxWidth?: number | string;
maxHeight?: number | string;
// overlay panel 的文本方向。 Direction = 'ltr' | 'rtl'
direction?: Direction | Directionality;
// 当用户在历史中后退或前进时是否需要处理overlay。请注意,这通常不包括点击链接(除非用户正在使用 `HashLocationStrategy`)
disposeOnNavigation?: boolean = false;
2.2 OverlayContainer 浮层容器
OverlayContainer 提供了一个容器元素的引用,浮层中的每个元素都渲染在其中。默认情况下,浮层容器会直接附加到文档的 body 中,这样就不会被带有 overflow: hidden 的父元素裁剪掉了。
方法 | 说明 |
---|---|
getContainerElement(): HTMLElement | 返回overlay容器元素 。如果已有容器元素则直接返回,如果没有则:创建一个样式名为cdk-overlay-container的div元素并追加到document的body末尾,用于包裹全部的浮层元素。 |
ngOnDestroy() | 销毁overlay容器元素 |
部分源码:
在开源组件库ngx-tethys的dialog中的体现:
2.3 Overlay 服务
2.3.1 Overlay服务对外提供了两个方法
方法 | 说明 |
---|---|
create(config?: OverlayConfig): OverlayRef{} | 创建一个overlay浮层。 |
position(): OverlayPositionBuilder{} | 获取可用于通过 fluent API 构建和配置位置策略的位置构建器OverlayPositionBuilder |
2.3.2 创建浮层
调用 overlay.create() 将返回一个 OverlayRef 实例。该实例用于管理那个特定浮层。
OverlayRef 是一个 PortalOutlet。一旦创建它,就可以为它附加一个 Portal 来添加内容。
const overlayRef = overlay.create();
const userProfilePortal = new ComponentPortal(UserProfile);
overlayRef.attach(userProfilePortal);
2.3.3 create方法具体做了什么?
第一步:获取或创建overlay容器元素(overlay container element)
获取已有的overlay容器元素,如果没有则:创建一个带有“cdk-overlay-container”样式类的 div作为overlay容器元素并把它追加到document body上。
第二步:创建overlay宿主元素(overlay host element)
创建一个宿主元素div (that wraps around an overlay and can be used for advanced positioning),并把它追加到容器元素上。
第三步:创建overlay面板元素(overlay pane element)
创建一个面板元素div,设置它的id为cdk-overlay-xx,同时设置它的样式cdk-overlay-pane,并把它追加到宿主元素上。
第四步:创建一个可以用于放Portal内容的插槽 DomPortalOutlet,Portal最终会被挂载到overlay pane元素上。
Portal 可以是 Component、TemplateRef 或 DOM 元素,可以被动态渲染到页面上的空白插槽(PortalOutlet)中。
// 创建一个可以用于放Portal内容的插槽 DomPor