Background: When the select component is used in the project, when the state of the drop-down box appears after clicking Select, the drop-down box of the slide page does not slide with the Select component. That is, not fixed below the select component. So I started thinking: how does ANTD implement the drop-down box? How does the dropdown follow the scroll?

Let’s start with solutions:

View the API documentation:

GetPopupContainer: Menu (drop-down box) render parent node. The default rendering is on the body. If you’re having trouble with menu scrolling, try changing it to the scrolling area and positioning it relative to it.

GetPopupContainer takes a function as an argument. When executed, the function accepts the argument triggerNode passed by the component and returns the parent node of the menu rendering. So you can set:

getPopupContainer={(triggerNode) = > triggerNode.parentNode}
Copy the code

The parent node of the menu rendering is antD’s Select component. Of course you can set any other node to be the parent of the drop-down box. Note, however, that the drop-down box is absolutely positioned, so for sliding to work, it is best to set the parent node to relative positioning (absolute positioning is also possible, but pay attention to the position of elements at the same level as the parent node). Otherwise, the dropdown continues to look up for elements that aren’t static, and you might find document.body.

Implement the principle of the drop-down component analysis

When the getPopupContainer property is not set, by default an absolutely positioned DIV (the parent of the dropdown) is generated under the body node when the dropdown component is first triggered:

When trigger appears dropdown box (dropdown box) :

According to triggerNode and body to calculate the value of the left and top: (offsetTop/offsetLeft/offsetHeight/offsetWidth)

Once the parent of the drop-down box is created, it will not be uninstalled even if the drop-down box is removed. . In other words, the location of the parent node of the drop-down box is determined, and the left/right of the drop-down box calculated each time is determined. So this is what happens when the sliding area of the select component is not the same height as the document.body. The drop-down box does not adsorb. Just find a parent component that slides relative to the Select component (relative position unchanged) and use it as the parent of the drop-down component.

Case 1. Place the drop-down box component under the SELECT component:

getPopupContainer={(triggerNode) = > triggerNode.parentNode}
Copy the code

.ant-select:{position:relative,... }

Case 2. Placed under the parent component that slides relative to the SELECT component, the difficulty needs to analyze to find the parent component.

Select #mainContent as parent, #rootContent set height to 100%, calculated according to the height of the parent element (100vh), so the relative position of body and select is changed (the height is not consistent). Body cannot be selected because all react_grid_items are absolutely positioned elements. The parent of the select element is 32px high, if set

getPopupContainer={(triggerNode) = > triggerNode.parentNode}
Copy the code

The drop – down box is blocked by the next absolute react_grid_item element. So I chose to make the drop-down box equal to #mainContent

What you learned

You can use this approach to implement a component with a drop-down box, identify the parent component, and generate an element to determine the location of the drop-down box.