一、场景

  1. 在开发过程中,会使用很多的SelectDatePicker等组件,当这些组件在可滚动的区域内滚动时,你会发现该组件的选项框也会跟着滚动,产生分离<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属性

  1. // getPopupContainer={(triggerNode: any) => triggerNode.parentNode}
  2. // triggerNode:当前元素的节点
  3. // triggerNode.parentNode:最近的父级元素节点
  4. // 在Select、DatePicker、Cascader添加getPopupContainer属性栗子:
  5. <div id='getPopupContainerDiv'>
  6. <Select
  7. defaultValue="1"
  8. getPopupContainer={(triggerNode: any) => triggerNode.parentNode}
  9. >
  10. <Option value="1">选项1</Option>
  11. <Option value="2">选项2</Option>
  12. </Select>
  13. <DatePicker
  14. getPopupContainer={(triggerNode: any) => triggerNode.parentNode}
  15. format="YYYY-MM-DD"
  16. />
  17. <Cascader
  18. getPopupContainer={(triggerNode: any) => triggerNode.parentNode}
  19. options={options}
  20. />
  21. </div>

设置完成之后,发现antd4.x中Select是没有分离的,但是DatePicker和Cascader还是会分离。但在3.x是正常的。打印三个组件的triggerNode以及triggerNode.parentNode如下。

Select的triggerNode以及triggerNode.parentNode

  image.png

DatePicker和Cascader的triggerNode以及triggerNode.parentNode

  image.png
三个组件的triggerNode.parentNode有差异,DatePicker和Cascader直接找到了最外层的div,他的节点还是在最外层,导致分离。
解决方法:直接定位到本身节点,将getPopupContainer代码修改一番,如下:

  1. getPopupContainer={(triggerNode: any) => triggerNode}

三、全局设置getPopupContainer  

  1. // 一般来说,项目中会用到很多这种选择组件,那么需要全局配置。
  2. <ConfigProvider locale={zh_CN} getPopupContainer={(node: any) => node}>
  3. <Route />
  4. </ConfigProvider >

四、全局配置后,在Modal中使用报错解决

  全局配置由于版本原因,如果一个项目挂载到不同的站点导致报错,例如p站antd3.0版本和w站antd4.0版本ant3.x版本报错,4.x版本直接空白
  image.png
官方API解释:全局设置getPopupContainer 触发节点,Modal 用法不存在 triggerNode导致报错
解决方法:增加一个判断条件

  1. <ConfigProvider
  2. locale={znCN}
  3. getPopupContainer={(node: any) => {
  4. const popupContainer = document.getElementById('popupContainer') || node;
  5. if (node) {
  6. // 目前只全局处理select和picker分离问题,如其他组件分离此处添加配置
  7. if (
  8. node.className.indexOf('ant-select-selector') > -1 ||
  9. node.className.indexOf('ant-picker') > -1 ||
  10. node.className.indexOf('anticon-history') > -1
  11. ) {
  12. return popupContainer;
  13. }
  14. }
  15. return document.body;
  16. }}
  17. >
  18. <Layout className={styles.pageContainer} id="popupContainer">
  19. {props.children}
  20. </Layout>
  21. </ConfigProvider>