因为笔者最近使用的两个组件库是arco和Element,所以笔者拿两个最近使用的作为比较
Dialog/Drawer
Element
Element的对话框/抽屉是如何全局的?其本质就是,你dialog写在哪里,他dom就生成在哪里,其是通过fixed定位来制定弹窗位置的,那么fixed怎么定位?这里放mdn
https://developer.mozilla.org/zh-CN/docs/Web/CSS/position
简单来说,fixed大部分情况以屏幕视口(viewport)来制定,但一旦元素祖先有transform等属性,就会以祖先为视口,所以Element的dialog的祖先一旦有平移旋转,就会按照祖先来:(
Arco
Arco的对话框和抽屉一样,是将对话框生成在body下面,即他的dom生成在body下,arco也是使用fixed定位,但这种方法相比element,出问题的概率会低很多。
Z-index
不知道有没有想过这个问题,就是在多层嵌套的情况下,比如抽屉中开抽屉,是如何保证页面顺序正常的?
首先来看Element
Element的实现方法其实很好理解,即全局维护一个z-index基数,然后每次调用全局样式的时候,index基数+1,这个看起来是一个比较好的办法,但这个方法的漏洞非常明显,如果子组件能够控制母组件的开关,则母组件打开的时候会在顶层,即下面这个动图
而arco,arco是在第一次打开(创建)的时候,把这个抽屉放到放在body下的母dom中,然后对于所有的抽屉/弹窗,都按照打开(创建)的顺序在母dom中排序,所有dom没有设置ZIndex,在这种情况下,上面的问题则会"正常"展示(其实并没有正常不正常,最终展现要看需求)
不过这个方案同样有个问题,即一旦对话框在先前被打开了,最里面点击对话框仍然无法呈现在最上面
问题解决:
- 两个对话框没必要共用一个实例,如果一定需要的话,可以在对话框取消的时候销毁dom。
- 可以通过设置zIndex来解决,但不推荐这么做
ToolTip/Select…
先说结论,这类的组件无论是Arco还是Element都是放到body下面的(Element为什么不能把dialog也放在全局?),不过有时候会发现一个问题,在官方文档中,打开了之后滚动,浮框可以跟着一起滚动,但很多时候我们自己应用的时候是不跟着一起滚动的,这是因为生成位置的时候,是根据点击位置与body之间的距离来定位的,而非视口来定位,而一旦我们的组件在自己的scroll中滚动(或者像微前端这种方案),所以在自己的滚动跳中没法滚动,解决方案就是getPopupContainer这个属性,传入你需要挂载的dom,且如果是dom同层级的情况使用相对定位的话,可能存在被BFC隔断(微前端)的情况。
Q.E.D.