如何在用户使用颜色选择器选色时禁用滚动区域的滚动?
移动端选色时禁用Radix UI滚动区域滚动的解决方案
实现思路
在颜色选择器展开时,动态修改Radix UI滚动区域的滚动属性,阻止触摸手势触发滚动;选择完成或关闭选择器后,恢复原有滚动行为。
具体实现
1. 基于组件状态控制滚动区域样式
利用React状态跟踪颜色选择器的显示状态,给Radix UI的ScrollArea组件动态设置样式:
import { ScrollArea } from '@radix-ui/react-scroll-area'; import { ChromePicker } from 'react-color'; import { useState } from 'react'; export default function ColorPickerWithScroll() { const [isPickerOpen, setIsPickerOpen] = useState(false); const [selectedColor, setSelectedColor] = useState('#ffffff'); return ( <ScrollArea style={{ // 禁用/恢复滚动 overflow: isPickerOpen ? 'hidden' : 'auto', // 阻止移动端触摸滚动手势 touchAction: isPickerOpen ? 'none' : 'auto' }} className="your-scroll-area-class" > {/* 滚动区域内的内容 */} <div className="content"> <button onClick={() => setIsPickerOpen(true)}>选择颜色</button> {isPickerOpen && ( <ChromePicker color={selectedColor} onChange={(color) => setSelectedColor(color.hex)} onClose={() => setIsPickerOpen(false)} /> )} </div> </ScrollArea> ); }
2. 全局禁用触摸滚动(备选方案)
如果组件级的控制不生效,可以通过修改document.body的样式全局禁用滚动:
import { useEffect, useState } from 'react'; // 导入组件... export default function ColorPickerWithScroll() { const [isPickerOpen, setIsPickerOpen] = useState(false); // 其他状态... useEffect(() => { if (isPickerOpen) { // 全局禁用触摸滚动和页面滚动 document.body.style.touchAction = 'none'; document.body.style.overflow = 'hidden'; } else { // 恢复原有样式 document.body.style.touchAction = ''; document.body.style.overflow = ''; } // 组件卸载时清理样式 return () => { document.body.style.touchAction = ''; document.body.style.overflow = ''; }; }, [isPickerOpen]); // 组件渲染部分... }
关键注意点
- 必须在颜色选择器关闭时完全恢复滚动状态,避免影响页面其他交互。
touch-action: none会禁用所有触摸手势(包括缩放),如果需要保留特定手势,可以调整为touch-action: pan-x或touch-action: pan-y等更精确的取值。
内容的提问来源于stack exchange,提问作者Jan D.M.
相关产品推荐
相关产品推荐

