|
|
|
# BI.Layers.create方法参数原理解释
|
|
|
|
|
|
|
|
今天看了一个BUG,通过BI.Layers创建的蒙层,在窗口大小改变时候没有随之改变。
|
|
|
|
|
|
|
|
先看FineUI中Layer.create方法的描述
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
create<T>(name: string, from?: any, op?: any, context?: any): T;
|
|
|
|
```
|
|
|
|
|
|
|
|
推荐的统一写法,下面会解释为何推荐这样写
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
const name; // your name
|
|
|
|
const container; // your container
|
|
|
|
BI.Layers.create(name, null, {
|
|
|
|
container: container,
|
|
|
|
render: {
|
|
|
|
type: "xxx",
|
|
|
|
},
|
|
|
|
}).show(name);
|
|
|
|
```
|
|
|
|
|
|
|
|
我们重点关注`from`属性和`op.container`属性
|
|
|
|
|
|
|
|
from属性控制的是,layer相对定位的元素.通过控制 `position: fixed` 搭配`top`,`left`,`width`,`height`属性,遮罩覆盖到对应元素上.同时监听元素resize事件,动态的更新宽高,使之一直"覆盖"在目标元素上
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
const name = BI.UUID();
|
|
|
|
const form = this.element;
|
|
|
|
BI.Layers.create(name, form, {
|
|
|
|
type: "xxx",
|
|
|
|
}).show(name);
|
|
|
|
```
|
|
|
|
|
|
|
|
这样实现有什么弊端吗?举个例子,具体业务中经常有需要创建一个layer遮罩在某个页面上,做一些具体操作的场景. 以定时调度新建任务为例:创建layer后,拖动容器宽度,会发现有明显的延迟.
|
|
|
|
这是因为resize事件的监听并不是实时的,做了节流.因此导致触发更新宽度慢了一拍.
|
|
|
|
|
|
|
|
![示例](../images/38.gif)
|
|
|
|
|
|
|
|
`op.container`属性又是什么作用呢,其控制的是弹出层在DOM树中属于哪个节点的子节点.默认情况下Layer弹出层是挂载到body下面的.
|
|
|
|
指定container之后,layer层将以position:absolute的形式,挂载到对于container节点下面.
|
|
|
|
|
|
|
|
当未指定form参数的时候,Layer层将以绝对布局形式固定相对container定位.在此场景下,宽高尺寸的动态调整全由浏览器渲染引擎自动控制.
|
|
|
|
根据[absolute定位的特性](./41.绝对布局的隐藏知识点.md),当`top:0;left:0`且元素未指定宽度时,绝对定位元素将随定位元素动态改变大小
|
|
|
|
这样再调整宽高,缩放等场景下表现就很顺滑了
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
const name = BI.UUID();
|
|
|
|
BI.Layers.create(name, null, {
|
|
|
|
container: this.element,
|
|
|
|
render: {
|
|
|
|
type: "xxx",
|
|
|
|
},
|
|
|
|
}).show(name);
|
|
|
|
```
|
|
|
|
|
|
|
|
![示例2](../images/39.gif)
|
|
|
|
|
|
|
|
既然指定form参数有这些弊端,为什么还要保留这个设计呢.当遇到layer弹出层中存在下拉框,气泡等特殊场景的时候.layer挂在到body上面可以避免这些痛点.
|
|
|
|
当然这种场景属于特事特办,需要开发者对stacking context和combo原理有深入的理解
|