一、场景
在开发过程中,会使用很多的Select、DatePicker等组件,当这些组件在可滚动的区域内滚动时,你会发现该组件的选项框也会跟着滚动,产生分离<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/113629/1645874287282-4d0cad47-93e6-4b33-aca4-6da33fca00be.png#clientId=u77f68b33-3a9d-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=1213&id=u26a67ff5&margin=%5Bobject%20Object%5D&name=image.png&originHeight=2426&originWidth=4488&originalType=binary&ratio=1&rotation=0&showTitle=false&size=575468&status=done&style=none&taskId=udfa9a359-818d-4690-bc28-4c1d107ffa8&title=&width=2244)
二、解决方法
官方给我们提供了getPopupContainer属性,该属性是菜单渲染的父节点,默认是body。只要添加该属性,设置好父节点,就可以解决这种分离。
添加getPopupContainer属性
// getPopupContainer={(triggerNode: any) => triggerNode.parentNode}
// triggerNode:当前元素的节点
// triggerNode.parentNode:最近的父级元素节点
// 在Select、DatePicker、Cascader添加getPopupContainer属性栗子:
<div id='getPopupContainerDiv'>
<Select
defaultValue="1"
getPopupContainer={(triggerNode: any) => triggerNode.parentNode}
>
<Option value="1">选项1</Option>
<Option value="2">选项2</Option>
</Select>
<DatePicker
getPopupContainer={(triggerNode: any) => triggerNode.parentNode}
format="YYYY-MM-DD"
/>
<Cascader
getPopupContainer={(triggerNode: any) => triggerNode.parentNode}
options={options}
/>
</div>
设置完成之后,发现antd4.x中Select是没有分离的,但是DatePicker和Cascader还是会分离。但在3.x是正常的。打印三个组件的triggerNode以及triggerNode.parentNode如下。
Select的triggerNode以及triggerNode.parentNode
DatePicker和Cascader的triggerNode以及triggerNode.parentNode
三个组件的triggerNode.parentNode有差异,DatePicker和Cascader直接找到了最外层的div,他的节点还是在最外层,导致分离。
解决方法:直接定位到本身节点,将getPopupContainer代码修改一番,如下:
getPopupContainer={(triggerNode: any) => triggerNode}
三、全局设置getPopupContainer
// 一般来说,项目中会用到很多这种选择组件,那么需要全局配置。
<ConfigProvider locale={zh_CN} getPopupContainer={(node: any) => node}>
<Route />
</ConfigProvider >
四、全局配置后,在Modal中使用报错解决
全局配置由于版本原因,如果一个项目挂载到不同的站点导致报错,例如p站antd3.0版本和w站antd4.0版本ant3.x版本报错,4.x版本直接空白
官方API解释:全局设置getPopupContainer
触发节点,Modal 用法不存在 triggerNode导致报错
解决方法:增加一个判断条件
<ConfigProvider
locale={znCN}
getPopupContainer={(node: any) => {
const popupContainer = document.getElementById('popupContainer') || node;
if (node) {
// 目前只全局处理select和picker分离问题,如其他组件分离此处添加配置
if (
node.className.indexOf('ant-select-selector') > -1 ||
node.className.indexOf('ant-picker') > -1 ||
node.className.indexOf('anticon-history') > -1
) {
return popupContainer;
}
}
return document.body;
}}
>
<Layout className={styles.pageContainer} id="popupContainer">
{props.children}
</Layout>
</ConfigProvider>