Colorpicker弹窗超出当前视口,如何检测后调整为在按钮上方显示

解决方案
核心实现逻辑为:弹窗展开时实时计算按钮下方的视口剩余空间,若剩余空间不足以容纳弹窗,则自动切换为向上定位。具体修改如下:
第一步:新增定位状态与位置判断逻辑
import { useState, useRef, useEffect } from 'react' // 原有逻辑之外新增状态和ref const [isPlacedTop, setIsPlacedTop] = useState(false) const popover = useRef(null) const pickerRef = useRef(null) // 用于获取Picker容器的位置信息 // 监听弹窗展开状态,触发位置计算 useEffect(() => { if (isOpen && popover.current && pickerRef.current) { const pickerRect = pickerRef.current.getBoundingClientRect() const popoverRect = popover.current.getBoundingClientRect() // 计算按钮下方的剩余视口高度 const bottomSpace = window.innerHeight - pickerRect.bottom // 剩余高度小于弹窗高度时,改为上方显示 setIsPlacedTop(bottomSpace < popoverRect.height) } }, [isOpen])
第二步:调整样式组件,支持动态定位
注意原有PopOver样式中的bottom: 20rem为冲突配置,会干扰定位逻辑,需要删除,新增动态定位规则:
const Picker = styled.div` position: absolute; display: flex; flex-direction: row; align-items: center; justify-content: flex-start; `; const Swatch = styled.div` width: 28px; height: 28px; border-radius: 8px; border: 3px solid #fff; box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1), inset 0 0 0 1px rgba(0, 0, 0, 0.1); cursor: pointer; `; const PopOver = styled.div` position: absolute; z-index: 100; /* 动态切换定位方向 */ ${props => props.isPlacedTop ? ` bottom: calc(100% + 2px); top: auto; ` : ` top: calc(100% + 2px); bottom: auto; `} left: 6rem; border-radius: 9px; box-shadow: 0 6px 12px rgba(0, 0, 0, 0.15); `;
第三步:修改组件结构绑定对应ref
<Picker ref={pickerRef}> <Label>{label}</Label> {isOpen && ( <PopOver ref={popover} isPlacedTop={isPlacedTop}> <HexColorPicker color={color} onChange={onChange} /> </PopOver> )} <Swatch style={{ backgroundColor: color }} onClick={() => toggle(!isOpen)} /> </Picker>
如果需要适配页面滚动时的位置变化,可额外监听window的scroll事件,重复执行上述位置判断逻辑即可。
内容的提问来源于stack exchange,提问作者agobago
相关产品推荐
相关产品推荐

